2010-12-07 15 views
5
UIPopoverController *historyPop = [[UIPopoverController alloc] initWithContentViewController:nav]; 
    [nav release]; 
    [historyPop setPopoverContentSize:CGSizeMake(400, 500)]; 
    [historyPop presentPopoverFromRect:CGRectMake(button.frame.origin.x, button.frame.origin.y, button.frame.size.width, 5) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES]; 
    //[historyPop release]; 

Ceci est mon code actuel, mais l'analyseur dit que c'est probablement une fuite, ce qui est le cas (comme la ligne de libération est commentée). Mais si je décommente la ligne de sortie alors l'application plante et dit que dealloc a été atteint sur le popover alors qu'il est encore visible, alors quand devrais-je libérer le contrôleur popover?UIPopoverController et la gestion de la mémoire

Répondre

5

Comme mentionné dans plusieurs endroits, les méthodes qui présentent un popover (soit d'un rect ou d'un bouton de la barre d'outils) ne conservent pas le popover. Ainsi, votre contrôleur de vue de présentation doit contenir une référence et le libérer au moment opportun.

Vous pouvez le faire en réglant le contrôleur de vue de présenter comme délégué du popover, comme mentionné. Une approche plus simple, mais légèrement moins efficace sur le plan de la mémoire, consiste à déclarer une propriété retain pour contenir UIPopoverController. Lorsque vous créez le popover, vous l'attribuez à la propriété, qui le conserve. Si vous créez ultérieurement un autre survol, il libère le popover précédent lorsque vous réaffectez la propriété. N'oubliez pas de libérer la propriété dans la méthode dealloc du contrôleur de présentation de présentation (ainsi que dans viewDidUnload).

Cette approche ne fuira pas, et vous n'avez pas besoin de traiter avec les délégués. Mais, vous garderez potentiellement un objet UIPopoverController plus longtemps que nécessaire. C'est à vous de déterminer si c'est un problème pour votre application.

+0

La définition du contrôleur de présentation en tant que délégué de UIPopoverController ne conserve pas le contrôleur de survol. Le point d'utilisation du délégué est que vous pouvez libérer de manière appropriée le contrôleur popover lorsque vous recevez l'appel 'popoverControllerDidDismissPopover:'. Donc, faire les deux a le plus de sens. –

+1

Il est sanglant ennuyeux qu'ils ne conservent pas lors de la présentation, et il dismatches complètement d'autres méthodes similaires (telles que la présentation de vues modales, ajoutant subviews) –

+0

Remarque: si vous allez à la route non-délégué, vous obtiendrez un « [UIPopoverController dealloc] atteint alors que popover est encore visible "si l'utilisateur rejette le pop-over et charge immédiatement un autre pop-over - le premier prend du temps pour devenir" non-visible "et finira par être déséquilibré avant qu'il ne finisse, provoquant un accident. – Jason

2

Essayez de libérer le popover: [historyPop autorelease]. presentPopoverFromRect ne conserve pas le popover, autorelease ne fonctionnera pas ici. Vous devez configurer votre classe en tant que délégué du contrôleur popover et libérer le popover au popoverControllerDidDismissPopover:.

+0

la même erreur se produit –

+2

Désolé, mon erreur - 'presentPopoverFromRect' ne conserve pas le popover, donc autorelease ne fonctionnera pas ici. Vous devez configurer votre classe en tant que délégué du contrôleur popover et libérer le popover dans 'popoverControllerDidDismissPopover:'. Voir la deuxième réponse à cette question: http://stackoverflow.com/questions/2867709/retain-release-pattern-for-uipopovercontroller-uiactionsheet-and-modal-view-con – bosmacs

+0

probablement la peine de modifier votre réponse à inclure votre commentaire, Toute personne qui lit la réponse mais pas les commentaires sera induite en erreur –