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?

Author: XJones, 2012-09-22

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
}
 17
Author: XJones,
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