web-dev-qa-db-fra.com

iOS6 viewDidUnload obsolète

C'est peut-être une mauvaise pratique, mais à partir des documentations que j'ai lues, j'ai eu le conseil d'initialiser des objets dans certains cas à l'intérieur de la méthode viewDidLoad et de le mettre à zéro dans viewDidUnload.

Par exemple, si vous avez quelque chose comme l'ajout d'un observateur

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(filterready:)
                                                 name:@"filterReady"
                                               object:nil];

Maintenant, je n'ai pas de méthode pour supprimer l'Observer, mais viewDidLoad est appelé à chaque fois que la vue est affichée, ce qui entraîne l'exécution de plusieurs observateurs après un certain temps et le sélecteur est ensuite appelé plusieurs fois.

Je peux résoudre ce problème en déplaçant certains nettoyeurs dans la méthode viewDidDisappear, mais maintenant j'ai des doutes si je fais la bonne chose.

Dans mon exemple, j'ai plusieurs contrôleurs de navigation qui contrôlent leurs sous-navigations, mais le dealloc n'est jamais appelé pour eux, même s'ils ne sont pas référencés

60
Hons

Vous devez utiliser les méthodes - (void)didReceiveMemoryWarning et - (void)dealloc.

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 devez tester que la vue n'est pas dans une fenêtre avant de le faire.

Vous devez donc d'abord vérifier si votre vue est dans la fenêtre, puis supprimer votre observateur dans le didReceiveMemoryWarning

107
Alex Rouse

Tout d'abord, même lorsque viewDidUnload n'était pas obsolète, vous devez avoir dû désenregistrer cette notification dans viewDidUnload ET dealloc. Même avant iOS 6, viewDidUnload n'est PAS appelé dans la plupart des cas; uniquement dans des situations de mémoire insuffisante. Donc, si vous l'aviez seulement mis dans viewDidUnload et non dealloc auparavant, il n'aurait pas été désenregistré et il se serait probablement écrasé lors de sa désallocation et de sa réception d'une notification. Vous devez donc avoir dû le mettre dans dealloc avant, pour que cela fonctionne correctement.

Deuxièmement, si vous l'avez fait correctement auparavant, vous n'avez rien à faire pour qu'il fonctionne correctement dans iOS 6. La seule différence dans iOS 6 est que les vues ne sont plus du tout déchargées (même dans les situations de faible mémoire). C'est donc la même chose que dans iOS 5 lorsque vous n'avez pas rencontré de mémoire insuffisante. Comme les vues ne sont pas déchargées, viewDidLoad ne sera appelée qu'une seule fois, donc votre notification ne sera enregistrée qu'une seule fois. Il ne sera pas enregistré dans dealloc, car vous devez l'avoir mis pour qu'il fonctionne correctement.

14
user102008

La réponse d'Alex est bonne. Mais j'aime bien l'appariement. Pour cette raison, sauf si la vue doit être notifiée lorsqu'elle n'est même pas vue, j'ajoute généralement une notification à viewWillAppear et viewDidDisappear

10
Anonymous White

Pourquoi ne pas simplement supprimer l'observateur dans la fonction DEALLOC? Et si vous utilisez ARC, n'appelez pas [super dealloc]

Si vous voyez que la fonction de désaffectation du contrôleur n'est pas appelée, vous devez découvrir pourquoi. Vous avez peut-être un NSTimer en cours d'exécution sur le ViewController et lorsque vous ouvrez la vue, cela entraînerait le dealloc pour ne pas être appelé. Ou la vue est conservée ailleurs.

4
Dan H