2010-12-07 7 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]; 

Dies ist mein aktueller Code, aber der Analysator sagt, dass das wahrscheinlich ein Leck ist, das es gibt (da die Freigabeleitung auskommentiert ist). Aber wenn ich die Freigabelinie auslasse, stürzt die App ab und sagt, dass dealloc auf dem Popover erreicht wurde, während es noch sichtbar ist, also wann genau sollte ich den Popover-Controller freigeben?UIPopoverController und Speichermanagement

Antwort

5

Wie an mehreren Stellen erwähnt, behalten die Methoden, die ein Popover darstellen (entweder von einem Rechteck oder von einer Symbolleistenschaltfläche), das Popover nicht zurück. Daher muss Ihr präsentierender View-Controller einen Verweis darauf halten und ihn zur richtigen Zeit freigeben.

Sie können dies tun, indem Sie den Presenting-View-Controller als Delegierten des Popover festlegen, wie bereits erwähnt. Ein einfacherer, wenn auch etwas weniger speichereffizienter Ansatz besteht darin, eine Retain-Eigenschaft zu deklarieren, die den UIPopoverController enthält. Wenn Sie das Popover erstellen, weisen Sie es der Eigenschaft zu, die es behält. Wenn Sie später ein anderes Popover erstellen, wird das vorherige Popover freigegeben, wenn Sie die Eigenschaft neu zuweisen. Vergessen Sie nicht, die Eigenschaft in der Dealloc-Methode des presenting view controllers (sowie viewDidUnload) freizugeben.

Dieser Ansatz wird nicht undicht, und Sie müssen nicht mit Delegaten umgehen. Sie werden jedoch möglicherweise ein UIPopoverController-Objekt länger als nötig beibehalten. Es liegt an Ihnen, festzustellen, ob dies für Ihre App von Bedeutung ist.

+0

Die Einstellung des Darstellungsansicht-Controllers als Delegat des UIPopoverControllers behält den Popover-Controller nicht bei. Der Zweck der Verwendung des Delegaten besteht darin, dass Sie den Popover-Controller ordnungsgemäß freigeben können, wenn Sie den Aufruf "popoverControllerDidDismissPopover:" erhalten. Das macht beides am sinnvollsten. –

+1

Es ist verdammt lästig, dass sie beim Präsentieren nicht beibehalten werden und andere ähnliche Methoden (z. B. das Präsentieren von Modalansichten und das Hinzufügen von Unteransichten) völlig ignorieren –

+0

Hinweis: Wenn Sie die nicht delegierte Route verwenden, erhalten Sie einen "UIPopoverController dealloc] erreicht, während das Popover noch sichtbar ist "wenn der Benutzer den Pop-Over-Vorgang abbricht und sofort einen weiteren Pop-Over lädt - der erste braucht Zeit, um" nicht sichtbar "zu bekommen und wird dann beendet, bevor er beendet wird, einen Absturz verursachen. – Jason

2

Versuchen Sie die automatische Freigabe des Popover: [historyPop autorelease]. presentPopoverFromRect behält das Popover nicht bei, daher funktioniert Autorelease hier nicht. Sie müssen Ihre Klasse als Delegat des Popover-Controllers einrichten und das Popover in popoverControllerDidDismissPopover: freigeben.

+0

der gleiche Fehler auftritt –

+2

Sorry, mein Fehler - 'PresentPopoverFromRect' behält das Popover nicht, so dass Autorelease hier nicht funktioniert. Sie müssen Ihre Klasse als Delegate des Popover-Controllers einrichten und das Popover in 'popoverControllerDidDismissPopover:' freigeben. Siehe die zweite Antwort auf diese Frage: http://stackoverflow.com/questions/2867709/retain-release-pattern-for-uipopovercontroller-uiactionsheet-and-modal-view-con – bosmacs

+0

wahrscheinlich lohnt es sich, Ihre Antwort zu bearbeiten, um Ihren Kommentar aufzunehmen, da jeder, der die Antwort, aber nicht die Kommentare liest, in die Irre geführt wird –

Verwandte Themen