2015-01-25 3 views
2

Я отклоняю текущий контроллер на свой корневой контроллер.iOS: Контрольные контроллеры не освобождаются при отклонении

[navigationController popToRootViewControllerAnimated:YES]; 

Однако все контроллеры просматривать в навигационных контроллеров не выпустили (я могу сказать, потому что методы в классах контроллера, вызывается дважды и метод dealloc не вызывается). Мне нужен совет, что делать, чтобы понять, почему это происходит. Есть ли какой-то конкретный способ, чтобы я отклонил контроллеры или, возможно, что-то еще происходит. Я использую ARC.

+0

Что вам говорят инструменты? – quellish

+1

При использовании ARC не предоставляется, что объекты будут немедленно выпущены.Вы случайно держите ссылку на контроллеры где-то в другом месте? – mAu

+0

Вы устанавливаете 'navigationController = nil;' где-нибудь? Пожалуйста, разместите весь свой код, который ссылается на переменную 'navigationController'. –

ответ

3

Возможно, это связано с несколькими причинами, но вы, скорее всего, придерживаетесь сильного указателя на viewController s, который вы видите. Один случай, когда один viewController является delegate другому viewController, а delegate - Strong, поэтому два viewController s держат сильный указатель друг на друга.

Удостоверьтесь, что нет другого объекта, содержащего сильный указатель на viewController.

0

Контроллер, который вы выпадаете, он сохраняется от фактически живого viewController. Это все. У вас есть 2 решения:

  • Когда вы нажимаете viewController, создать его на месте:

    UIViewController *vc = [UIViewController initWith...]; 
    [navigationController pushViewController:vc animated:YES]; 
    
  • Другое решение есть weak ссылку на него:

    //Property in the interface 
    @property (nonatomic, weak) UIViewController *vc; 
    
    //In the method 
    _vc = [UIViewController initWith...]; 
    [navigationController pushViewController:vc animated:YES]; 
    

Когда выйдет viewController, не имея других ссылок, будет b e освобожден.

Cheers!

3

В дополнение к возможности ссылки на делегата, вы также должны проверить любые блоки, в которых используете свой контроллер, и всегда использовать слабую ссылку на это, когда внутри блока.

От компании Apple docs:

enter image description here

Давайте предположим, что вы собираетесь сделать запрос HTTP и отображать информацию о пользователе, который вы получаете от сервера, на ваш взгляд зрения контроллера.

- (void)requestUserInfo 
{ 
    [self.client makeGETRequest:@"http://example.org/user/1/" usingBlock:^(User *user, NSError *error) { 
      if (error) { 
       [self.errorView displayWithError:error]; 
      } 
      else { 
       self.userView.user = user; 
       [self.userView setNeedsLayout]; 
      } 
    }]; 
} 

В этом случае, когда пользователь становится скучно ожидания запроса, чтобы вернуть результат и отводы кнопку «Назад», чтобы просто закрыть страницу, вид контроллера не будет освобождаться, пока запрос не выполняется загрузка и выполнение блока , Вы можете видеть это сами, переопределяя dealloc.

Таким образом, если не требуется, всегда используйте __weak ссылки на self внутри блоков.

- (void)requestUserInfo 
{ 
    __weak UIViewController *weakSelf = self; 

    [self.client makeGETRequest:@"http://example.org/user/1/" usingBlock:^(User *user, NSError *error) { 
      if (error) { 
       [weakSelf.errorView displayWithError:error]; 
      } 
      else { 
       weakSelf.userView.user = user; 
       [weakSelf.userView setNeedsLayout]; 
      } 
    }]; 
} 
Смежные вопросы