memory management em Objective-C

Duplicatas possíveis:
Aprenda Gerenciamento de Memória Obj-C
Onde estão as melhores explicações de gerenciamento de memory para o iPhone?

Eu venho de um plano de fundo C / C ++ e a natureza dinâmica do Objective-C é um pouco estranho para mim, há um bom recurso que alguém pode apontar para algumas técnicas básicas de gerenciamento de memory em Objective-C? ex. retendo, liberando, autoreleasing

Por exemplo, é completamente ilegal usar um ponteiro para um object Objective-C e tratá-lo como um array? Você é forçado a usar NSArray e NSMutableArray para estruturas de dados?

Eu sei que estas são perguntas muito novas, obrigado por qualquer ajuda que você possa me oferecer.

Aqui vai você :

memory management do aplicativo é o processo de alocação de memory durante o tempo de execução do seu programa, usando-o e liberando-o quando você estiver pronto. Um programa bem escrito usa o mínimo de memory possível. Em Objective-C, ele também pode ser visto como uma maneira de distribuir a propriedade de resources limitados de memory entre muitos dados e códigos. Quando terminar de trabalhar com este guia, você terá o conhecimento necessário para gerenciar a memory do seu aplicativo gerenciando explicitamente o ciclo de vida dos objects e liberando-os quando eles não forem mais necessários.

Embora o gerenciamento de memory seja normalmente considerado no nível de um object individual, seu objective é realmente gerenciar charts de objects. Você quer ter certeza de que não tem mais objects na memory do que realmente precisa …

Geralmente não é útil repetir as regras básicas de gerenciamento de memory, já que quase invariavelmente você comete um erro ou as descreve incompletamente – como é o caso nas respostas fornecidas por ‘heckj’ e ‘benzado’ …

As regras fundamentais do gerenciamento de memory são fornecidas na documentação da Apple em Regras de gerenciamento de memory .

A propósito da resposta de “www.stray-bits.com”: afirmar que os objects retornados de methods “não proprietários” são “autoreleased” também é, na melhor das hipóteses, enganoso. Você normalmente não deve pensar em termos de se algo é ou não “liberado automaticamente”, mas simplesmente considerar as regras de gerenciamento de memory e determinar se pelas convenções você possui o object retornado. Se você fizer isso, você precisa renunciar à propriedade …

Um contra-exemplo (para pensar em termos de objects autoreleased) é quando você está considerando problemas de desempenho relacionados a methods como stringWithFormat: Como você normalmente (1) não tem controle direto sobre a vida útil desses objects, eles podem persistir por um tempo comparativamente longo e aumentar desnecessariamente o espaço ocupado pela memory do seu aplicativo. Enquanto na área de trabalho isso pode ser de pouca importância, em plataformas mais restritas isso pode ser um problema significativo. Portanto, é considerada a melhor prática em todas as plataformas usar o padrão de alloc / init e, em plataformas mais restritas, sempre que possível, você é fortemente desencorajado a usar quaisquer methods que levem a objects liberados automaticamente.

(1) Você pode assumir o controle usando seus próprios pools de autorelease locais. Para mais informações, consulte o Guia de programação de gerenciamento de memory da Apple .

Se for uma matriz, sinta-se à vontade para iterar com um ponteiro. Matrizes regulares ainda são governadas por C. Se for um NSArray, leia os documentos do NSArray. Se eles dizem para fazer isso de uma maneira particular, faça dessa maneira. Ao escrever para o OS X, faça isso pelo livro.

Objective-C é apenas um superconjunto de C. Tudo o que você pode fazer em C é válido em Objective-C.

Você certamente pode usar matrizes e fazer seu próprio gerenciamento de memory. O maior componente é que se você está criando algo que é uma subclass NSObject, e você cria com um método [XXX alloc], ou se você obtê-lo de outra cópia com [xxx copy], então você tem a responsabilidade de combine isso com uma versão associada.

Se conseguir uma variável de qualquer lugar e pretender mantê-la por mais do que o uso imediato que você está executando, então certifique-se de invocar um [… reter] nela.

O link http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html contém todos os detalhes e é definitivamente o primeiro lugar para ler.

Aqui estão as regras:

  1. Se você criar um object chamando alloc ou copy , você o possui e deve release lo quando terminar.
  2. Se você não criou um object, mas deseja garantir que ele permaneça antes que o controle retorne ao loop de execução (ou, para manter as coisas simples, o método retorna), envie uma mensagem de retain e release -a mais tarde quando você ‘ re feito.
  3. Se você criar um object e quiser devolvê-lo de seu método, você é obrigado a liberá-lo, mas não quer destruí-lo antes que o chamador tenha a chance de vê-lo. Então, você envia-o autorelease lugar, o que o coloca no Pool de Liberação Automática, que é esvaziado assim que o controle retorna ao loop de events do programa. Se ninguém mais mantiver o object, ele será desalocado.

Em relação aos arrays, você é livre para fazer algo assim:

 NSObject *threeObjects[3]; threeObjects[0] = @"a string"; threeObjects[1] = [NSNumber numberWithInt:2]; threeObjects[2] = someOtherObject; 

Razões para usar o NSArray de qualquer maneira:

  • O NSArray cuidará da retenção de objects à medida que você os adiciona e os libera ao removê-los, enquanto em um array C simples você terá que fazer isso sozinho.
  • Se você está passando um array como um parâmetro, um NSArray pode relatar a contagem de objects que ele contém, com um array C simples, você precisará passar uma contagem também.
  • Misturar significados de colchetes em uma linha parece estranho:

    [threeObjects[0] length]

Lembre-se de que, se você usar uma matriz de estilo C para armazenar objects e decidir usar a garbage collection, precisará alocá-la com NSAllocateCollectable(sizeof(id)*size, NSScannedOption) e marcar essa variável como __strong .

Dessa forma, o coletor sabe que ele contém objects e tratará os objects armazenados como raízes durante o tempo de vida dessas variables.

Por exemplo, é completamente ilegal usar um ponteiro para um object Objective C e tratá-lo como um array?

Se não é um array, então sim.

Você é forçado a usar NSArray e NSMutableArray para estruturas de dados?

Não. Você pode usar arrays C, e você deve ser capaz de usar vetores STL em C ++ (embora eu não use C ++, então não sei detalhes específicos de como).

Mas não há razão para não usar NS{,Mutable}Array . Não tema os frameworks de cacau, pois eles são seus amigos.

E não se esqueça dos outros tipos de coleção, como NS{,Mutable}Set e NS{,Mutable}Dictionary .

Como outro novato, achei as palestras do stanford iOS muito úteis: http://itunes.apple.com/itunes-u/developing-apps-for-ios-hd/id395605774

É bom porque mostra os conceitos em ação com demos, e geralmente acho que alguém falando comigo absorve melhor do que apenas lendo.

Eu definitivamente acho que é um desses tópicos que você tem que aprender e reaprender através de diferentes fonts … apenas para marcanvasr isso em sua cabeça.

Provavelmente também é útil notar que para mensagens de class como NSString + (NSString *) stringWithFormat: (basicamente, mensagens auxiliares que alocam um object para você em vez de exigir que você aloque o object), o object resultante é liberado automaticamente, a menos que você explicitamente retê-lo.