2009-08-28 6 views
0

J'ai donc modifié l'exemple PageControl d'Apple pour charger dynamiquement divers contrôleurs de navigation (ainsi que leurs contrôleurs de vue racine) dans la vue déroulante. J'ai également ajouté une technique qui tente de décharger un contrôleur de navigation quand il n'est plus nécessaire. Je ne suis à ObjC que depuis un peu plus d'un mois, donc je ne suis pas sûr de faire le déchargement correctement. S'il vous plaît voir mon code ci-dessous, suivi de mes questions.Déchargement des ViewControllers de l'exemple PageControl d'Apple + Relation entre UINavigationController et ses contrôleurs RootView


D'abord, je crée un tableau mutable et le remplir avec des valeurs nulles, tout comme le fait d'Apple:

// Create dummy array for viewControllers array, fill it with nulls, and assign to viewControllers 
NSMutableArray *array = [[NSMutableArray alloc] init]; 
for (unsigned i = 0; i <= kNumberOfPages; i++) 
{ 
    [array addObject:[NSNull null]]; 
} 

self.viewControllers = array; 
[array release]; 

... Plus tard, je remplir le tableau avec des objets UINavigationController comme si (ce est juste un code partiel, excusez s'il vous plaît les parties manquantes ... l'idée principale est que j'attribue un couple de choses, les assigne et ensuite libère):

id controller = [[classForViewController alloc] initWithNibName:NSStringFromClass(classForViewController) bundle:nil]; 
    navController = [[UINavigationController alloc] initWithRootViewController:controller]; 
    [controller release]; 
    [self.viewControllers replaceObjectAtIndex:page withObject:navController]; 
    [navController release]; 

... Enfin, si une page n'a pas besoin d'être plus chargé que je fais ceci:

[self.viewControllers replaceObjectAtIndex:i withObject:[NSNull null]]; 

Questions:

  1. je crois comprendre qu'une fois Je remplace le contrôleur de navigation dans mon tableau viewControllers avec null, le tableau libère le contrôleur de navigation. Ainsi, le compte de retenue du contrôleur de navigation atteint zéro et n'occupe plus de mémoire. Est-ce correct? Qu'en est-il du contrôleur de vue racine à l'intérieur du contrôleur de navigation?

  2. Ai-je besoin de faire quoi que ce soit ou est-il libéré automatiquement une fois que le compte de retenue du contrôleur de navigation a atteint zéro?

Merci!

Répondre

1
  1. Oui. Tout objet placé dans une collection reçoit un message retain. De même, tout objet retiré d'une collection reçoit un message release, la cause de la suppression n'est pas pertinente.
  2. Oui, tous les objets libéreront tous les objets dont ils sont propriétaires lorsqu'ils seront libérés.

tout cela se résume au simple principe de la propriété que le cacao définit:

  • Vous possédez l'objet si vous l'avez reçu en tant que valeur de retour en appelant une méthode:
    1. est nommé alloc ou new.
    2. Contient le mot copier, tel que copy et mutableCopy.
  • Vous possédez l'objet si vous appelez retain.
  • Vous pouvez seulement appeler release et autorelease sur les objets que vous possédez.
  • Vous devez libérer tous les objets appartenant à vos méthodes dealloc.

Il existe une seule exception; les délégués ne sont jamais possédés. C'est pour éviter les références circulaires et les fuites de mémoire qu'elles provoquent.

Comme un effet secondaire, cela signifie aussi que lorsque vous vous implémentez une méthode, vous devez retourner un objet libéré automatique à moins que vous implémentez new, ou une méthode avec copier dans son nom. Les objets renvoyés en tant qu'arguments sont toujours auto-libérés. Suivez-le strictement et Objective-C peut être traité comme s'il s'agissait d'ordures collectées 95% du temps.

+0

Merci. Rétrospectivement, cela semble évident et je me sens un peu bête d'avoir posé cette question, mais j'avais juste besoin de confirmer ma compréhension :) – iPhoneToucher

+0

La plupart des choses dans le cacao sont évidentes quand on les comprend. Parfois, les comprendre peut être assez dur puisque Cocoa ne ressemble à rien d'autre :). – PeyloW

0

Vraisemblablement oui, une fois que votre nombre de retenues atteint zéro (peu importe le moment ou le moment), votre objet recevra le message dealloc. Vous pouvez mettre un point d'arrêt pour vous assurer que cela se produit. Instruments est livré avec un utilitaire de fuites qui devrait vous aider à trouver des problèmes de mémoire, c'est un excellent outil et je suggère de l'utiliser fréquemment.

Je ne suis pas tout à fait sûr de ce que vous entendez par "faire quoi que ce soit". Je présume que vous voulez dire le libérer. Le modèle général est que si vous alloc ou retain, vous release. Vous pouvez approximativement deviner s'il va y avoir un problème si vos allocs et retenues dépassent vos versions (ou vice versa, vous ne voulez pas doubler la version).

Questions connexes