2009-08-17 33 views
45

Hinweis: Diese Frage ist outdated- viewDidUnload veraltet iOS 6.Wann wird UIViewController viewDidUnload aufgerufen?

Wenn nicht automatisch UIViewController der ViewDidUnload aufgerufen? Ja, ich weiß, wenn die Sicht entladen wird. Aber wann passiert das automatisch? Wie kann ich es manuell machen? Vielen Dank.

+4

Es sieht so aus, als würde es nicht unbedingt aufgerufen; Ein UIViewController kann ohne Zuweisen von viewDidUnload freigegeben werden. – beetstra

+0

Nach ausführlichen Tests sehe ich definitiv, dass viewDidUnload manchmal nicht aufgerufen werden kann. Ich sehe, dass View-Controller ohne Aufruf von viewDidUnload dealloc'd werden. –

+0

Diese Frage sollte entfernt werden. viewDidUnload ist veraltet und wird in iOS 6 nicht mehr aufgerufen. –

Antwort

42

Wenn Sie eine Speicherwarnung im Simulator ausgeben (siehe Menü), wird diese für jeden View Controller aufgerufen, der an eine nicht sichtbare Ansicht angehängt ist.

Dies liegt daran, dass View-Controller standardmäßig für Speicherwarnungsbenachrichtigungen registriert sind und alle Views, die derzeit nicht verwendet werden, vom View-Controller entladen werden. Die viewDidUnload-Methode ist vorhanden, sodass Sie alles weitere löschen können , um zusätzlichen Speicher zu sparen (oder wenn Sie einige IBOutlets beibehalten haben, um Speicher freizugeben, der ansonsten durch die entladene Ansicht freigegeben würde).

Im Allgemeinen sollten alle IBOutlets, die Sie in dealloc freigeben, auch in dieser Methode freigegeben (und Referenzen auf null gesetzt).

+0

Es wird dann nicht für meine App aufgerufen, weil ich immer nur einen View Controller zu einer Zeit instanziiert habe, wenn ich sie zuerst umschalte (ich sele.vc = nil) (nachdem ich die Superview entfernt habe). – mk12

+0

Ich verwende keine IBOutlets, ich benutze IB nicht. – mk12

+0

Ich bin ziemlich sicher, dass Sie richtig sind, wenn Sie nur eine VC zu einer Zeit haben, dann würde die Ansicht nie entladen werden. Der häufigste Fall ist, wenn Sie einen Navigationscontroller verwenden und die Ansichten, von denen Sie weg navigiert sind, immer noch vorhanden sind ... Auch wenn Sie IB nicht verwenden, wenn Sie Subviews hinzufügen, die Sie Referenzen für die gleiche Regel behalten möchten - nil out die Referenz (obwohl dies in Ihrem Fall wiederum nicht zutrifft). –

17

-viewDidUnload aufgerufen wird, wenn die Ansicht des Viewcontroller-Eigenschaft auf null gesetzt wird, entweder manuell oder am häufigsten durch didReceiveMemoryWarning:.

+0

Ich habe ein Szenario, wo ich möchte -viewDidUnload auf meinem UIViewController ausgelöst werden, die von einem UIPopoverController gehostet wurde. Nachdem das Popover beendet wurde, lösche ich manuell die Ansicht des View-Controllers, aber -viewDidUnload wird immer noch nicht ausgelöst. Irgendwelche Ideen warum nicht? – dreyln

+0

Haben Sie in viewDidUnload einen Haltepunkt gesetzt, um zu bestätigen, dass er nicht ausgelöst wird? Stellen Sie sicher, dass Ihr Code, der die Ansicht auf Null setzt, tatsächlich auf den richtigen Ansichtscontroller verweist (stellen Sie sicher, dass der Ansichtscontroller selbst zu diesem Zeitpunkt nicht Null ist und dass sein Wert dem erwarteten Wert entspricht). Die häufigste Ursache für diese Art von Problemen ist versehentlich ein zusätzlicher View-Controller, der nicht auf dem Bildschirm angezeigt wird. –

+0

Ja, ich hatte einen Haltepunkt und einen Code, der einen Timer ungültig macht. Der Haltepunkt wurde nie getroffen und mein Timer lief weiter (protokollierte Nachrichten an der Konsole). Ich habe auch überprüft, dass der ContentViewController meines Popover der richtige war und nicht Null. Ich frage mich, ob die Ansicht noch technisch sichtbar ist. Ich ignoriere die Ansicht in der Methode -popoverControllerDidDismissPopover:. – dreyln

37

Zusätzlich manuell eine Speicherwarnung im Simulator Ausgabe, können Sie eine programmatisch mit

- (void)_simulateLowMemoryWarning { 
    // Send out MemoryWarningNotification 
    [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidReceiveMemoryWarningNotification 
                 object:[UIApplication sharedApplication]]; 
    // Manually call applicationDidReceiveMemoryWarning 
    [[[UIApplication sharedApplication] delegate] applicationDidReceiveMemoryWarning:[UIApplication sharedApplication]]; 
} 

Sie können ausgeben können dann dazu führen, das alle 5 Sekunden passieren einen Timer

static NSTimer *gLowMemoryTimer = nil; 

- (void)stopLowMemoryTimer { 
    [gLowMemoryTimer invalidate]; 
    gLowMemoryTimer = nil; 
} 

- (void)startLowMemoryTimer { 
    if (gLowMemoryTimer) { 
    [self _stopLowMemoryTimer]; 
    } 
    gLowMemoryTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(_simulateLowMemoryWarning) userInfo:nil repeats:YES]; 
} 
+6

Brilliante Idee, um eine App zu testen. – Guillaume

+0

Dies ist eine großartige Idee, aber da dies nur zum Testen verwendet werden würde, wäre es wahrscheinlich am besten, die private Methode in UIApplication zu verwenden, die aufgerufen wird, wenn eine echte Speicherwarnung auftritt, falls sie etwas anderes tut: UIApplication sharedApplication] performSelector: @selector (_performMemoryWarning)]; ' –

3

ViewDidUnload mit in wenig Speicherbedingungen aufgerufen. Wir sollten Sachen, die wir in der viewDidLoad-Methode geladen haben, entladen. Wir müssen den Besitz eines Objekts aufgeben, indem wir die accessor-Methode aufrufen, um es auf null zu setzen. Im Falle einer Steckdose löst sich das Objekt selbst, so dass die Objektreferenz sicher auf Null gesetzt werden kann. Wenn es sich nicht um eine synthetisierte Eigenschaft handelt, müssen wir erst das Objekt freigeben, als wir es auf null gesetzt haben. in iOS auf die viewDidUnload API vorgelegt 6 nämlich, dass in iOS 6 viewDidUnload keine

9

iOS 6.x und später

Ich weiß, das ist eine ältere Frage, aber ich fühle mich eine Antwort in Bezug auf die Änderungen werden soll, ist länger genannt (überhaupt) und ist veraltet.

+2

Außerdem sollten Sie bei Implementierung mit iOS 5 noch eine' viewDidUnload'-Implementierung schreiben, aber es ist wichtig, dass Sie keine Logik haben, die unter iOS ausgeführt werden müsste 6 dort. – mxcl

Verwandte Themen