14

Je ne suis pas très clair sur les modèles de propriété d'objet requis pour les instances suivantes. Lorsque mon UIViewController présente un contrôleur de survol, une feuille d'action ou un autre contrôleur de vue comme modal, dois-je conserver une référence conservée à ce contrôleur enfant jusqu'à ce qu'il soit rejeté? En d'autres termes, est-ce que les lignes de code suivantes "transfèrent" effectivement la propriété, ou pas?Conserver/libérer le modèle pour les contrôleurs UIPopoverController, UIActionSheet et modal view?

[aPopoverController presentPopoverFromBarButtonItem:someButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:NO]; 

[anActionSheet showFromBarButtonItem:someButtonItem animated:NO]; 

[aViewController presentModalViewController:someOtherViewController animated:YES]; 

Quelqu'un peut-il me diriger vers une documentation explicite à ce sujet?

Répondre

26

UIPopoverViewController possède une légère gestion/propriété de mémoire différente. Présenter un popover ne conserve pas la mémoire, vous ne pouvez donc pas transférer la propriété de votre popviewcontroller à l'objet présentateur.

Pour éviter la fuite de mémoire, vous devez adopter la UIPopoverControllerDelegate et mettre en œuvre la méthode de DidDismissPopOver comme suit:

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { 
    [popoverController release]; 
} 

De cette façon, vous pouvez alloc sûr et présenter un PopOver:

-(void)showSearch:(id)sender { 
    SearchViewController *searchVC = [[SearchViewController alloc] init]; 
    UIPopoverController *popVC = [[UIPopoverController alloc] initWithContentViewController:searchVC]; 
    popVC.delegate = self; 
    [popVC setPopoverContentSize:CGSizeMake(320, 100)]; 
    [popVC presentPopoverFromRect:CGRectMake(200, 200, 320, 100) inView:self.view permittedArrowDirections:0 animated:YES]; 
    [searchVC release]; 
} 
+1

Attention, searchVC fuit si vous le faites de cette façon. Ajouter une autorelease. – steipete

+0

Oui, searchVC a fui. Au lieu d'une autorelease, une version simple fonctionnera également. Ajouter ceci à la dernière ligne: '[searchVC release];' –

+1

Comme la documentation pour 'popoverControllerDidDismissPopover:' dit: _ "Le contrôleur popover n'appelle pas cette méthode en réponse aux appels programmatiques à la méthode dismissPopoverAnimated: Si vous rejeter le popover par programme, vous devez effectuer toutes les actions de nettoyage immédiatement après avoir appelé la méthode dismissPopoverAnimated: ". Donc, si vous utilisez 'dismissPopoverAnimated:' vous devrez également appeler la version après, sinon vous aurez une fuite. – ivanzoid

1

La présentation d'un contrôleur de vue modale conserve UIViewController. Ce n'est pas clair d'après les docs. Cependant, je l'ai testé en utilisant le code suivant ...

NSLog(@"BEFORE %d", [self.setupViewController retainCount]); 
[self.navigationController presentModalViewController:self.setupViewController animated:YES]; 
NSLog(@"AFTER %d", [self.setupViewController retainCount]); 

Le self.setupViewController est déjà retenu sur place, mais présentant génèrerait les éléments suivants:

2010-05-19 10:07:36.687 LocateMe[27716:207] BEFORE 1 
2010-05-19 10:07:36.762 LocateMe[27716:207] AFTER 3 

Il est donc probablement être retenue dans la la propriété modalViewController locale, ainsi que dans la hiérarchie de vues. Le rejeter équilibrera ces derniers.

Donc, la ligne du bas est, gardez-le si vous voulez le contrôler directement, mais vous n'avez pas à le faire.

EDIT - Pour être clair, le modèle correct consiste à toujours conserver un objet si vous vous définissez comme délégué. C'est parce que vous devriez mettre le délégué à zéro dans votre dealloc pour la sécurité. Pratiquement cependant, un contrôleur modal va toujours être renvoyé avant que vous ne vous libérez, donc ce n'est pas un problème. Vous remarquerez qu'Apple rompt également cette règle dans [UIView setAnimationDelegate:], qui conserve le délégué que vous avez défini.

+0

Je voudrais ajoutez également qu'une grande partie de l'exemple de code d'Apple initialise un UIViewController, le présente de manière modale, puis le libère. Consultez l'exemple AddMusic. – DougW

+0

Est-ce la même chose pour les popovers et les feuilles d'action? –

+0

Oui, vous pouvez déclencher UIAlertView, puis le relâcher. Ou vous pouvez le conserver si vous voulez faire quelque chose. De toute façon, c'est bien, assurez-vous juste d'équilibrer vos retenues/communiqués. – DougW

Questions connexes