2010-02-14 9 views
20

Ich neige dazu, meine Sachen in -dealloc zu lösen, und jetzt 3.0 iPhone OS dieses lustige -viewDidUnload Verfahren eingeführt, wo sie sagen:Was genau muss ich in ViewDidUnload tun?

// Lassen Sie jede Subviews von Ansicht der Haupt beibehalten. // z.B. self.myOutlet = null;

So -viewDidUnload scheint aufgerufen zu werden, wenn die Ansicht des View-Controllers aus dem Speicher gelöscht wurde. Und wenn ich Subviews an die Hauptansicht des View-Controllers angehängt habe, muss ich diese Sachen nur HIER veröffentlichen, aber nicht in -dealloc?

Das ist verwirrend. Was passiert, wenn -dealloc bewirkt, dass die Ansicht entladen (freigegeben) wird? Dann wird es wieder aufrufen - ViewDidUnload?

Ich erkenne den Unterschied, dass -viewDidUnload nur für den Fall ist, wo die Ansicht selbst getötet wird, aber der View-Controller im Speicher bleibt. Und -dealloc ist für den Fall, dass die ganze Sache in den Müll geht.

Vielleicht kann jemand die Verwirrung klären.

+1

Ähnliche Fragen: http://stackoverflow.com/questions/1158788/when-should-i-release-objects-in-voidviewdidunload-rather-than-in-dealloc –

+0

viewDidUnload ist in iOS 6 veraltet! – whyoz

Antwort

37

Die Absicht hier ist, "balancieren" Ihre Subview-Verwaltung. Alles, was Sie in viewDidLoad erstellen, sollte in viewDidUnload freigegeben werden. Dies macht es einfacher zu verfolgen, was wo veröffentlicht werden soll. In den meisten Fällen ist Ihre dealloc Methode ein Spiegelbild Ihrer init Methode, und Ihre viewDidUnload wird ein Spiegelbild Ihrer viewDidLoad Methode sein.

Wie Sie bereits erwähnt haben, sind die Methoden viewDid ... zu verwenden, wenn die Ansicht selbst geladen und entladen wird. Dies ermöglicht ein Nutzungsmuster, in dem die View-Controller in dem Speicher geladen bleiben, aber die Ansicht selbst kann je nach Bedarf auf- und abgeladen werden:

init 
viewDidLoad 
viewDidUnload 
viewDidLoad 
viewDidUnload 
... 
dealloc 

Natürlich ist es nicht weh tut Dinge in Ihrer dealloc Methode zur Freigabe als Nun, solange Sie sie auf nil setzen, wenn Sie sie in viewDidUnload freigeben.

Das folgende Zitat aus dem Memory Management Abschnitt von Apples UIViewController documentation, beschreibt es genauer:

... in iPhone OS 3.0 und höher kann die ViewDidUnload Verfahren eine geeignetere Stelle für die meisten Bedürfnisse sein .

Wenn eine Warnung mit geringem Speicher auftritt, löscht die UIViewController-Klasse ihre Ansichten, wenn sie weiß, dass sie sie später erneut laden oder neu erstellen kann. Wenn dies geschieht, ruft es auch die Methode viewDidUnload auf, um Ihrem Code die Möglichkeit zu geben, die Eigentumsrechte an Objekten, die Ihrer Ansichtshierarchie zugeordnet sind, einschließlich Objekten, die mit der nib-Datei geladen wurden, Objekte, die in Ihrer viewDidLoad-Methode erstellt wurden, und Objekte, die träge erstellt wurden, aufzugeben Laufzeit und zur Ansichtshierarchie hinzugefügt. Wenn Ihr Ansichtscontroller Outlets (Eigenschaften oder Rohvariablen, die das IBOutlet-Schlüsselwort enthalten) enthält, sollten Sie normalerweise die viewDidUnload-Methode verwenden, um die Eigentümerschaft dieser Outlets oder anderer nicht mehr benötigter viewbezogener Daten aufzugeben.

+0

viewDidUnload ist keine Spiegelung von viewDidLoad, da die Unload-Methode outlets auf null setzt. –

+1

Auf welche Entlade-Methode beziehen Sie sich? Ich habe einen Blick in die UIViewController-Dokumentation geworfen, aber ich habe keine Methode mit diesem Namen gefunden. Wenn ich viewDidUnload als (normalerweise) ein Spiegelbild von viewDidLoad beschreibe, meinte ich in Bezug auf die Speicherverwaltung; d. h. alles, was in viewDidLoad zugewiesen, kopiert oder beibehalten wurde, sollte in viewDidUnload freigegeben werden. IBOutlets werden normalerweise automatisch konfiguriert, wenn Ihre NIB-Datei geladen wird. Selbst wenn sie vor dem Aufruf von viewDidUnload auf null gesetzt sind, sollte dies aus Sicht des Speichers keine Auswirkungen haben. –

+0

Um klar zu sein; Ich kann sehen, wie es möglich wäre * in Schwierigkeiten zu geraten, wenn Sie ein Objekt in viewDidLoad zuweisen würden, auf das in viewDidUnload nicht zugegriffen werden könnte, wenn alle IBOutlets auf null gesetzt worden wären. Dies wäre jedoch ein starker Hinweis auf ein schlechtes Design, da ein Objekt immer einen Zeiger auf irgendeinen Speicher halten sollte, für den es freigegeben wird. –

3

Wie Sie sagen, wird viewDidUnload aufgerufen, wenn self.view = nil, dies tritt im Allgemeinen auf, wenn Sie Speicherwarnung erhalten. In dieser Methode müssen Sie eine Unteransicht der Hauptansicht freigeben, die einfach mit der .xib- oder loadView-Methode erstellt werden kann.Sie sollten jedes Datenobjekt freigeben, wenn Sie sie in viewDidload oder loadView usw. erstellen, da diese Methoden erneut aufgerufen werden, um dem Benutzer die Ansicht anzuzeigen. Diese Daten können problemlos wiederhergestellt werden.

0

Wenn Sie eine Speicherwarnung erhalten, wird der Viewcontroller normalerweise seine Ansicht entladen, aber selbst wird nicht freigegeben.
Alles, was leicht neu erstellt werden kann, sollte entladen werden, aber nicht das Modell der Ansicht.

Verwandte Themen