Wofür ist das -(void)viewDidUnload
gut?
Könnte ich nicht einfach alles neu veröffentlichen -dealloc
? Wenn die Ansicht entladen würde, würde -dealloc
sie trotzdem nicht aufgerufen werden?
Wofür ist das -(void)viewDidUnload
gut?
Könnte ich nicht einfach alles neu veröffentlichen -dealloc
? Wenn die Ansicht entladen würde, würde -dealloc
sie trotzdem nicht aufgerufen werden?
Antworten:
Zusätzlich zu dem, was bereits angedeutet wurde, wollte ich mehr über die Logik dahinter herausarbeiten -viewDidUnload
.
Einer der wichtigsten Gründe für die Implementierung ist, dass UIViewController
Unterklassen üblicherweise auch Verweise auf verschiedene Unteransichten in der Ansichtshierarchie enthalten. Diese Eigenschaften könnten beispielsweise IBOutlets
beim Laden von einer Schreibfeder oder programmgesteuert im Inneren festgelegt worden sein -loadView
.
Das zusätzliche Eigentum an Unteransichten UIViewController
bedeutet, dass selbst wenn ihre Ansicht aus der Ansichtshierarchie entfernt und freigegeben wird, um Speicher zu sparen, wodurch die Unteransichten auch von der Ansicht freigegeben werden, sie tatsächlich nicht freigegeben werden, da die UIViewController
selbst noch ihre eigene ausstehende enthält Beibehaltung von Verweisen auf diese Objekte. Durch die Freigabe des UIViewController
zusätzlichen Eigentums an diesen Objekten wird sichergestellt, dass sie auch für den freien Speicher freigegeben werden.
Die Objekte, die Sie hier freigeben, werden normalerweise neu erstellt und erneut festgelegt, wenn die UIViewController
Ansicht re-loaded
entweder von einer Schreibfeder oder über eine Implementierung von stammt -loadView
.
Beachten Sie auch, dass die UIViewController
view
Eigenschaft nil
zum Zeitpunkt des Aufrufs dieser Methode gültig ist.
Wie die Dokumentation sagt :
Es wird unter Bedingungen mit wenig Arbeitsspeicher aufgerufen, wenn der Ansichtscontroller seine Ansicht und alle mit dieser Ansicht verknüpften Objekte freigeben muss, um Speicher freizugeben.
In der gleichen Situation dealloc
wird nicht aufgerufen. Diese Methode ist nur in OS3 und höher verfügbar. Der Umgang mit der gleichen Situation in iPhone OS 2.x war ein echtes Problem!
Update Juli 2015 : Es sollte beachtet werden, dass dies viewDidUnload
in iOS 6 veraltet ist, da "Ansichten unter Bedingungen mit geringem Arbeitsspeicher nicht mehr gelöscht werden und diese Methode daher niemals aufgerufen wird." Der moderne Rat ist also, sich keine Sorgen zu machen und zu verwenden dealloc
.
Dies liegt daran, dass Sie normalerweise den @property
als "(nonatomic, retain)"
und als solchen festgelegten Setter festlegen, der das aktuelle Objekt freigibt und dann das Argument beibehält, d. H.
self.property = nil;
... macht etwas in der Art von:
[property release];
property = [nil retain];
Daher töten Sie zwei Fliegen mit einer Klappe: Speicherverwaltung (Freigeben des vorhandenen Objekts) und Zuweisen des Zeigers zu Null (da das Senden einer Nachricht an einen Null-Zeiger Null zurückgibt).
Hoffentlich hilft das.
Denken Sie daran, dass dies viewDidUnload
eine Methode im Ansichts-Controller ist, nicht in der Ansicht. Die Ansicht dealloc
Verfahren werden erhalten , wenn die Ansicht entlädt genannt, aber die Sicht Controller dealloc
Verfahren kann erst später genannt werden.
Wenn Sie eine Warnung zu wenig Arbeitsspeicher erhalten und Ihre Ansicht nicht angezeigt wird, was beispielsweise jedes Mal der Fall ist, wenn Sie einen UIImagePickerController verwenden, um dem Benutzer das Fotografieren zu ermöglichen, wird Ihre Ansicht entladen und muss danach neu geladen werden.
Fazit:
Ansichtscontroller haben eine Ansichtseigenschaft. Normalerweise fügt eine Schreibfeder oder ein Code dieser Ansicht andere Ansichten hinzu. Dies geschieht häufig innerhalb einer -viewDidLoad-Methode wie folgt:
- (void)viewDidLoad {
[super viewDidLoad];
[self createManyViewsAndAddThemToSelfDotView];
}
Darüber hinaus kann eine NIB-Datei eine Schaltfläche erstellen und an die Ansicht des View Controllers anhängen.
Unter iPhone OS 2.2 mussten Sie beim Aufrufen von -didReceiveMemoryWarning vom System etwas freigeben, um Speicherplatz freizugeben. Sie können die Ansicht des gesamten View Controllers freigeben, wenn dies sinnvoll ist. Oder einfach nur große speicherintensive Inhalte.
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
In dem neuen Betriebssystem 3.0 gibt es jetzt eine -viewDidUnload-Methode, die vom System aufgerufen wird, wenn die Ansicht aufgrund des geringen Arbeitsspeichers entladen wurde (bitte korrigieren Sie mich: Wann genau wird dies aufgerufen?)
-viewDidUnload wird verwendet, um alle Objekte freizugeben, die sowohl dem View Controller selbst als auch der View gehörten. Der Grund: Wenn ein Ansichtscontroller Verweise auf untergeordnete Elemente der Ansicht enthält, z. B. eine Schaltfläche, werden die referenzierten untergeordneten Ansichten nicht freigegeben, da ihre Aufbewahrungsanzahl> = 1 ist. Nachdem sie in -viewDidUnload freigegeben wurden, können sie freigegeben werden aus dem Gedächtnis.
Apple hat viewWillUnload abgelehnt. Jetzt sollten Sie didReceiveMemoryWarning oder Dealloc verwenden, um Ihre Objekte freizugeben.
In iOS 6 sind die Methoden viewWillUnload und viewDidUnload von UIViewController jetzt veraltet. Wenn Sie diese Methoden zum Freigeben von Daten verwendet haben, verwenden Sie stattdessen die didReceiveMemoryWarning-Methode. Mit dieser Methode können Sie auch Verweise auf die Ansicht des Ansichtscontrollers freigeben, wenn diese nicht verwendet wird. Sie müssen zuvor testen, ob sich die Ansicht nicht in einem Fenster befindet.
Wenn der Ansichtscontroller aus dem Navigationscontrollerstapel entfernt und an keiner anderen Stelle beibehalten wird, wird er freigegeben und anstelle von viewDidUnload wird die Freigabe aufgerufen. Sie sollten die in loadView erstellten Ansichten in dealloc freigeben, es ist jedoch nicht erforderlich, die Variablen auf nil zu setzen, da die Variablen kurz nach dem Aufruf von dealloc nicht mehr vorhanden sind.