Jaki jest właściwy sposób rozładowania widoków w iOS 6 w ostrzeżeniu pamięci (wada Apple doc)?
W systemie iOS 6, viewWillUnload
i viewDidUnload
są przestarzałe, a Uiviewcontrollery nie rozładowują widoków, które nie są widoczne na ekranie podczas ostrzeżenia o pamięci. Instrukcja programowania kontrolera widoku zawiera przykład ręcznego przywrócenia tego zachowania.
Oto przykład kodu:
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Add code to clean up any of your own resources that are no longer necessary.
if ([self.view window] == nil)
{
// Add code to preserve data stored in the views that might be
// needed later.
// Add code to clean up other strong references to the view in
// the view hierarchy.
self.view = nil;
}
}
Poniżej próbki kodu znajduje się następująca Uwaga:
Przy następnym dostępie do właściwości view widok jest przeładowywany dokładnie tak, jak to było pierwsze czas.
Jest tu oczywisty błąd. Jeśli kontroler widoku, który nie załadował swojego widoku, otrzyma ostrzeżenie o pamięci, załaduje swój widok w linii if ([self.view window] == nil)
, a następnie przystąpi do czyszczenia i ponownego zwolnienia go. W najlepszym razie jest to nieefektywne. W najgorszym przypadku pogarsza to warunki pamięci, jeśli wczytana jest złożona hierarchia widoków i dane pomocnicze. Zweryfikowałem to zachowanie w symulatorze iOS.
Z pewnością mogę kodować wokół tego, ale wydaje się dziwne Dla Apple docs mieć taki błąd. Coś przeoczyłem?
1 answers
Poprawne sprawdzenie w kontrolerze widoku dla ładowanego widoku i na ekranie to:
if ([self isViewLoaded] && [self.view window] == nil)
Moje pełne rozwiązanie w iOS 6, aby kontroler widoku rozładowywał widoki i czyścił podobne do iOS 5, jest następujące:
// will not be called in iOS 6, see iOS docs
- (void)viewWillUnload
{
[super viewWillUnload];
[self my_viewWillUnload];
}
// will not be called in iOS 6, see iOS docs
- (void)viewDidUnload
{
[super viewDidUnload];
[self my_viewDidUnload];
}
// in iOS 6, view is no longer unloaded so do it manually
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
if ([self isViewLoaded] && [self.view window] == nil) {
[self my_viewWillUnload];
self.view = nil;
[self my_viewDidUnload];
}
}
- (void)my_viewWillUnload
{
// prepare to unload view
}
- (void)my_viewDidUnload
{
// the view is unloaded, clean up as normal
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-10 16:09:26