Respostas:
Além do que já foi indicado, queria elaborar mais sobre a lógica por trás -viewDidUnload
.
Uma das razões mais importantes para implementá-lo é que as UIViewController
subclasses geralmente também contêm referências de propriedade a várias subvisualizações na hierarquia de visões. Essas propriedades podem ter sido definidas IBOutlets
durante o carregamento de uma ponta, ou programaticamente dentro -loadView
, por exemplo.
A propriedade adicional de subvisualizações UIViewController
significa que mesmo quando sua visão é removida da hierarquia de visão e liberada para economizar memória, através da qual as subvisualizações também são liberadas pela visão, elas não serão realmente desalocadas porque o UIViewController
próprio ainda contém seus próprios itens pendentes retendo referências a esses objetos também. Liberar a UIViewController
propriedade adicional desses objetos garante que eles também serão desalocados para liberar memória.
Os objetos que você libera aqui são geralmente recriados e configurados novamente quando a UIViewController
visualização é re-loaded
, de um Nib ou por meio de uma implementação de -loadView
.
Observe também que a UIViewController
view
propriedade está nil
no momento em que este método é chamado.
Como diz a documentação :
É chamado durante condições de pouca memória, quando o controlador de visualização precisa liberar sua visualização e quaisquer objetos associados a essa visualização para liberar memória.
Na mesma situação nãodealloc
é chamado. Este método está disponível apenas no OS3 e superior. Lidar com a mesma situação no iPhone OS 2.x foi uma verdadeira dor!
Atualização de julho de 2015 : deve-se observar que viewDidUnload
foi descontinuado no iOS 6 porque "as visualizações não são mais eliminadas em condições de pouca memória e, portanto, este método nunca é chamado." Portanto, o conselho moderno é não se preocupar com isso e usar dealloc
.
Isso ocorre porque você normalmente definirá o @property
como "(nonatomic, retain)"
e como tal, o configurador que é criado para você libera o objeto atual e, em seguida, retém o argumento, ou seja
self.property = nil;
... faz algo ao longo das linhas de:
[property release];
property = [nil retain];
Portanto, você está matando dois coelhos com uma cajadada só: gerenciamento de memória (liberando o objeto existente) e atribuindo o ponteiro a nil (já que enviar qualquer mensagem a um ponteiro nulo retornará nulo).
Espero que ajude.
Lembre-se de que viewDidUnload
é um método no controlador de visualização, não na visualização. O método da visão dealloc
será chamado quando a visão descarregar, mas o controlador da visão dealloc
método não pode ser chamado até mais tarde.
Se você receber um aviso de pouca memória e sua visualização não estiver aparecendo, o que acontecerá, por exemplo, sempre que você usar um UIImagePickerController para permitir que o usuário tire uma foto, sua visualização será descarregada e precisará ser recarregada depois disso.
Conclusão:
Controladores de visualização têm uma propriedade de visualização. Normalmente, uma ponta ou pedaço de código adiciona outras visualizações a esta visualização. Isso acontece frequentemente dentro de um método -viewDidLoad, como este:
- (void)viewDidLoad {
[super viewDidLoad];
[self createManyViewsAndAddThemToSelfDotView];
}
além disso, um arquivo nib pode criar um botão e anexá-lo à visualização do controlador de visualização.
No iPhone OS 2.2, quando -didReceiveMemoryWarning era invocado no sistema, era necessário liberar algo para liberar memória. Você poderia liberar toda a visão do controlador de visualização se isso fizesse sentido. Ou apenas conteúdos que consomem muita memória.
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
Agora, no novo OS 3.0, há um método -viewDidUnload, que será chamado do sistema quando a visualização for descarregada devido à falta de memória (corrija-me: quando exatamente isso é chamado?)
-viewDidUnload é usado para liberar todos os objetos que pertenciam ao próprio controlador de visualização e à visualização. O motivo: se um controlador de visualização contém referências a filhos da visualização, ou seja, um botão, as visualizações filho referenciadas não serão liberadas, porque sua contagem de retenção é> = 1. Depois de serem liberadas em -viewDidUnload, elas podem ser liberadas da memória.
O viewWillUnload obsoleto da Apple, agora você deve usar didReceiveMemoryWarning ou dealloc para liberar seus objetos.
No iOS 6, os métodos viewWillUnload e viewDidUnload de UIViewController foram descontinuados. Se você estava usando esses métodos para liberar dados, use o método didReceiveMemoryWarning. Você também pode usar este método para liberar referências à visão do controlador de visualização, se não estiver sendo usada. Você precisaria testar se a visualização não está em uma janela antes de fazer isso.
Se o controlador de visualização for retirado da pilha do controlador de navegação e não for retido em nenhum outro lugar, ele será desalocado e desalocado será chamado em vez de viewDidUnload. Você deve liberar as visualizações criadas em loadView em dealloc, mas não é necessário definir as variáveis como nulo, porque logo após o dealloc ser chamado, as variáveis não existirão mais.