gerenciamento de memória com propriedades
-
06-07-2019 - |
Pergunta
Eu estou começando a entender o gerenciamento de memória melhor em Objective-C, mas há algo que eu não entendo. Esta é uma declaração de propriedade:
@property (nonatomic, retain)UILabel *myLabel;
e este é o seu invisível setter sintetizado (eu acho):
- (void)setMyLabel:(UILabel *)newValue {
if(myLabel != newValue) {
[myLabel release];
myLabel = [newValue retain];
}
}
Que poupa todo o trabalho de manutenção e outras coisas cada vez, mas dizer que eu definir a minha propriedade pela primeira vez, o seu ainda não foi alocada pelo que a sua contagem de referência é 0, certo? Então eu faço
UILabel *tempLabel = [[UILabel alloc] init];
self.myLabel = tempLabel;
[tempLabel release];
Eu não sou realmente certo o que acontece lá, quando ele libera nada, mas dizem que a propriedade já tem um valor, e nós configurá-lo. No setter, primeiro ele fica liberado. Portanto, não que o tornam desaparecer? Se sua contagem de referência é um, e, em seguida, na setter sua liberado, como é que ficar em torno de ser definido para o retido novo valor?
Graças !!
Solução
Eu acho que você está confundindo objetos e referências. A propriedade é uma referência a um objeto, e não o próprio objeto. Quando você ligar ou desligar uma propriedade envia retém e lançamentos para os objetos que ele aponta para, mas a própria referência é parte do objeto que a propriedade está em (neste caso self).
Pode ser útil para ler sobre coisas como ponteiros e lvalues ??.
Outras dicas
O valor inicial de myLabel é nulo, por isso, o seu primeiro trabalho para a propriedade, ou seja
self.myLabel = tempLabel;
lançará nulo, ou seja, [liberação nil]. Em Objective C, enviando uma mensagem para nil é um não-op, então isso não fará nada.
Da mesma forma, em seu método dealloc, você deve ter:
[myLabel release];
O que vai lançar o myLabel se a propriedade já foi atribuído, equilibrar a [newValue reter] no setter. Se a propriedade nunca foi atribuído, então ainda será nulo, e de novo [a liberação nil] será um-op não.
Leia as de gerenciamento de memória para o regras exatas sobre quando você precisa para manter / objetos de libertação.
O objeto vai "desaparecer" (ou seja, ser desalocada) quando todas as posses sobre ele ter sido abandonada. Ou seja, quando (ou logo após) todos alloc / Copiar / novas chamadas foram equilibrados com libertação / chamadas disparo automático.
Eu sou relativamente novo para Objective-C também, mas gostaria de tentar responder a esta para re-afirmar o meu entendimento.
dizer que eu definir a minha propriedade pela primeira vez, o seu ainda não foi alocada pelo que a sua contagem de referência é 0, certo?
Sim, a manter a contagem é 0.
No setter, primeiro ele fica liberado. Portanto, não que o tornam desaparecer?
Ele subtrai 1 do manter a contagem de myLabel
. Se a manter a contagem de myLabel chegar a 0, os dados ou objeto que a variável myLabel
está apontando para será liberado da memória.
Se a sua contagem de referência é um, e, em seguida, na setter sua liberado, como é que ficar em torno de ser definido para o retido novo valor?
Nesse cenário, o myLabel
dados está apontando para será liberado (manter a contagem será 0) e myLabel
, então, apontar a zero (que é vazio). A variável é definida na classe e será sempre disponível para aceitar mensagens para que setter, de modo que os novos dados podem ser atribuídos a myLabel
se de myLabel
manter a contagem é 0 ou 100.