Pergunta

Se eu tiver algo como um UILabel vinculado a um arquivo xib, preciso liberá-lo no dealloc da minha visualização?A razão pela qual pergunto é porque não aloco, o que me faz pensar que também não preciso liberar?por exemplo (no cabeçalho):

IBOutlet UILabel *lblExample;

na implementação:

....
[lblExample setText:@"whatever"];
....

-(void)dealloc{
    [lblExample release];//?????????
}
Foi útil?

Solução

Se você seguir o que agora é considerado a melhor prática, você deve libere as propriedades de saída, porque você deveria tê-las mantido no acessador set:

@interface MyController : MySuperclass {
    Control *uiElement;
}
@property (nonatomic, retain) IBOutlet Control *uiElement;
@end


@implementation MyController

@synthesize uiElement;

- (void)dealloc {
    [uiElement release];
    [super dealloc];
}
@end

A vantagem desta abordagem é que ela torna a semântica de gerenciamento de memória explícita e clara, e funciona de forma consistente em todas as plataformas para todos os arquivos nib.

Observação:Os comentários a seguir se aplicam apenas ao iOS anterior à versão 3.0.Com 3.0 e posterior, você deve simplesmente anular os valores de propriedade em viewDidUnload.

Uma consideração aqui, porém, é quando seu controlador pode descartar sua interface de usuário e recarregá-la dinamicamente sob demanda (por exemplo, se você tiver um controlador de visualização que carregue uma visualização de um arquivo nib, mas mediante solicitação - digamos, sob pressão de memória -- libera-o, com a expectativa de que ele possa ser recarregado se a visualização for necessária novamente).Nessa situação, você deseja ter certeza de que, quando a visualização principal for descartada, você também renunciará à propriedade de quaisquer outros pontos de venda para que eles também possam ser desalocados.Para UIViewController, você pode lidar com esse problema substituindo setView: do seguinte modo:

- (void)setView:(UIView *)newView {
    if (newView == nil) {
        self.uiElement = nil;
    }
    [super setView:aView];
}

Infelizmente, isto dá origem a outra questão.Como UIViewController atualmente implementa seu dealloc método usando o setView: método acessador (em vez de simplesmente liberar a variável diretamente), self.anOutlet = nil será chamado dealloc bem como em resposta a um aviso de memória...Isto levará a uma falha dealloc.

A solução é garantir que as variáveis ​​de saída também sejam definidas para nil em dealloc:

- (void)dealloc {
    // release outlets and set variables to nil
    [anOutlet release], anOutlet = nil;
    [super dealloc];
}

Outras dicas

Encontrei o que procurava nos documentos da Apple.Resumindo, você pode configurar seus objetos como propriedades que você libera e retém (ou apenas @property, @synthesize), mas não é necessário fazer isso para coisas como UILabels:

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/chapter_3_section_4.html#//apple_ref/doc/uid/10000051i-CH4-SW18

O

[anOutlet release], anOutlet = nil;

Parte é completamente supérflua se você escreveu setView:corretamente.

Se você não liberá-lo no dealloc, isso aumentará o consumo de memória.

Veja mais detalhes aqui com o gráfico ObjectAlloc do instrumento

De certa forma, você aloca o rótulo criando-o no IB.

O que o IB faz é observar seus IBOutlets e como eles são definidos.Se você tiver uma variável de classe que IB deve atribuir uma referência a algum objeto, IB enviará uma mensagem de retenção para esse objeto para você.

Se você estiver usando propriedades, o IB fará uso da propriedade que você possui para definir o valor e não reter explicitamente o valor.Assim, você normalmente marcaria as propriedades IBOutlet como reter:

@property (nonatomic, retain) UILabel *lblExample;

Assim, no caso do éter (usando propriedades ou não), você deve chamar release em seu dealloc.

Qualquer IBOutlet que seja uma subview da view principal do seu Nib não precisa ser liberado, pois será enviada a mensagem de autorelease na criação do objeto.Os únicos IBOutlet que você precisa liberar em seu dealloc são objetos de nível superior, como controladores ou outros NSObjects.Tudo isso é mencionado no documento da Apple vinculado acima.

Se você não definir o IBOutlet como uma propriedade, mas simplesmente como uma variável de instância, você ainda deverá liberá-lo.Isso ocorre porque no initWithNib, a memória será alocada para todos os IBOutlets.Portanto, este é um dos casos especiais que você deve liberar, mesmo que não tenha retido ou alocado memória no código.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top