Подтвердить что ты не робот

Каков надлежащий способ выгрузки представлений в iOS 6 в предупреждении памяти (ошибка Apple doc)?

В iOS 6, viewWillUnload и viewDidUnload устарели, а UIViewControllers больше не выгружают представления, которые не отображаются на экране во время предупреждения о памяти. В руководстве View Programmingler Programming Guide приведен пример того, как вручную восстановить это поведение.

Вот пример кода:

- (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;
    }
}

Ниже образца кода следует отметить следующее:

При следующем доступе к виду свойства вид перезагружается точно так же, как это было в первый раз.

Здесь есть очевидный недостаток. Если контроллер просмотра, который не загрузил его представление, получает предупреждение о сохранении памяти, он загрузит его вид в строке if ([self.view window] == nil), а затем продолжит очистку и отпустите его снова. В лучшем случае это неэффективно. В худшем случае это ухудшает условия памяти, если загружена сложная иерархия представлений и поддерживающие данные. Я проверил это поведение в симуляторе iOS.

Я могу, конечно, кодировать вокруг этого, но кажется, что для документов Apple есть странная ошибка. Я что-то пропустил?

4b9b3361

Ответ 1

Правильная проверка в контроллере представления для загружаемого представления и на экране:

if ([self isViewLoaded] && [self.view window] == nil)

Мое полное решение в iOS 6, чтобы иметь диспетчер разметки просмотра и очистки, подобный iOS 5, выглядит следующим образом:

// 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
}