Réponses:
En plus de ce qui a déjà été indiqué, je voulais en dire plus sur la logique derrière -viewDidUnload
.
L'une des raisons les plus importantes de sa mise en œuvre est que les UIViewController
sous - classes contiennent généralement également des références propriétaires à diverses sous-vues dans la hiérarchie de vues. Ces propriétés peuvent avoir été définies IBOutlets
lors du chargement à partir d'une pointe, ou par programmation à l'intérieur -loadView
, par exemple.
La propriété supplémentaire des sous-vues par le UIViewController
fait que même lorsque sa vue est supprimée de la hiérarchie de vues et libérée pour économiser de la mémoire, à travers laquelle les sous-vues sont également libérées par la vue, elles ne seront pas réellement désallouées car le UIViewController
lui-même contient toujours son propre en suspens. en conservant également les références à ces objets. Libérer la UIViewController
propriété supplémentaire de ces objets garantit qu'ils seront également libérés pour libérer de la mémoire.
Les objets que vous libérez ici sont généralement recréés et définis à nouveau lorsque la UIViewController
vue est re-loaded
, soit à partir d'un Nib, soit via une implémentation de -loadView
.
Notez également que la UIViewController
view
propriété est nil
au moment où cette méthode est appelée.
Comme le dit la documentation :
Il est appelé dans des conditions de mémoire insuffisante lorsque le contrôleur de vue doit libérer sa vue et tous les objets associés à cette vue pour libérer de la mémoire.
Dans la même situation nedealloc
est pas appelé. Cette méthode n'est disponible que dans OS3 et supérieur. Faire face à la même situation dans iPhone OS 2.x était une vraie douleur!
Mise à jour de juillet 2015 : il convient de noter que viewDidUnload
cette méthode est obsolète dans iOS 6 car «Les vues ne sont plus purgées dans des conditions de mémoire insuffisante et cette méthode n'est donc jamais appelée». Ainsi, le conseil moderne est de ne pas s'en soucier et de l'utiliser dealloc
.
Ceci est dû au fait que vous définissez généralement @property
comme "(nonatomic, retain)"
et en tant que tel le setter qui est créé pour vous libère l'objet actuel et conserve ensuite l'argument ie
self.property = nil;
... fait quelque chose du genre:
[property release];
property = [nil retain];
Par conséquent, vous faites d'une pierre deux coups: la gestion de la mémoire (libérant l'objet existant) et l'affectation du pointeur à nil (car l'envoi de tout message à un pointeur nil renverra nil).
J'espère que cela pourra aider.
N'oubliez pas qu'il viewDidUnload
s'agit d'une méthode dans le contrôleur de vue, pas dans la vue. La méthode de la vue dealloc
sera appelée lors du déchargement de la vue, mais la méthode du contrôleur de vue dealloc
ne peut être appelée que plus tard.
Si vous recevez un avertissement de mémoire insuffisante et que votre vue ne s'affiche pas, ce qui se produira par exemple à chaque fois que vous utilisez un UIImagePickerController pour permettre à l'utilisateur de prendre une photo, votre vue sera déchargée et devra être rechargée après cela.
Conclusion:
Les contrôleurs de vue ont une propriété de vue. En règle générale, une pointe ou un morceau de code ajoute d'autres vues à cette vue. Cela se produit souvent dans une méthode -viewDidLoad, comme ceci:
- (void)viewDidLoad {
[super viewDidLoad];
[self createManyViewsAndAddThemToSelfDotView];
}
en outre, un fichier nib peut créer un bouton et l'ajouter à la vue du contrôleur de vue.
Sur iPhone OS 2.2, lorsque -didReceiveMemoryWarning était appelé depuis le système, vous deviez libérer quelque chose pour libérer de la mémoire. Vous pouvez libérer la vue entière du contrôleur de vue si cela a du sens. Ou tout simplement de gros contenus gourmands en mémoire.
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
Maintenant, dans le nouvel OS 3.0, il existe une méthode -viewDidUnload, qui sera appelée à partir du système lorsque la vue a été déchargée en raison d'une mémoire insuffisante (veuillez me corriger: quand exactement cela est-il appelé?)
-viewDidUnload est utilisé pour libérer tous les objets appartenant à la fois au contrôleur de vue lui-même et à la vue. La raison: si un contrôleur de vue contient des références aux fils de la vue, c'est-à-dire à un bouton, les vues enfants référencées ne seront pas libérées, car leur nombre de rétention est> = 1. Une fois qu'elles sont libérées dans -viewDidUnload, elles peuvent être libérées de mémoire.
ViewWillUnload est obsolète par Apple, vous devez maintenant utiliser didReceiveMemoryWarning ou dealloc pour libérer vos objets.
Dans iOS 6, les méthodes viewWillUnload et viewDidUnload de UIViewController sont désormais obsolètes. Si vous utilisiez ces méthodes pour libérer des données, utilisez plutôt la méthode didReceiveMemoryWarning. Vous pouvez également utiliser cette méthode pour libérer des références à la vue du contrôleur de vue si elle n'est pas utilisée. Vous devrez tester que la vue n'est pas dans une fenêtre avant de faire cela.
Si le contrôleur de vue est sorti de la pile du contrôleur de navigation et n'est conservé nulle part ailleurs, il sera désalloué et dealloc sera appelé à la place de viewDidUnload. Vous devez libérer les vues créées dans loadView dans dealloc, mais il n'est pas nécessaire de définir les variables sur nil, car peu de temps après l'appel de dealloc, les variables n'existeront plus.