2013-03-20 2 views
0

Класс My View Controller освобождается, когда приложение переходит в фоновый режим. Я использую ARC.My View Controller освобождается, когда приложение переходит на задний план

У меня есть UIViewController, который подписывается на уведомления, когда приложение становится активным и выполняет метод. Но как только приложение занимает около 30 секунд в фоновом режиме, а затем возобновляется, приложение вылетает с сообщением, отправленным на освобожденный экземпляр.

Включение объектов Zombie показывает, что сам контроллер просмотра является зомби.

Спасибо!

Инстанцирование моего контроллера представления (в AppDelegate):

UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; 
MyViewController *myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"]; 

Приоритетное уведомление в AppDelegate:

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationForegrounded object:self]; 
} 

Приоритетное уведомление в контроллере представления:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resumeForeground) name:kNotificationForegrounded object:nil]; 
} 

Я попытался создать сильную ссылку в AppDelegate, но контроллер представления по-прежнему будет освобождён:

@property (strong, nonatomic) MyViewController *myViewController; 

Я попытался добавить контроллер вид на массив и иметь сильную ссылку на массив в AppDelegae, но все же я получаю те же результаты:

@property (strong, nonatomic) NSMutableArray *viewControllers; 
//... 
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; 
MyViewController *myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"]; 
self.viewControllers = [[NSMutableArray alloc] init]; 
[self.viewControllers addObject:myViewController]; 

ответ

0

Вопрос:

  1. MyViewController был повторно инстанцирован каждый раз, когда MyViewController *myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"]; назывался.

  2. Использование ARC, похоже, когда приложение выходит на передний план, выполняется некоторая очистка.

  3. Когда приложение было перенесено на передний план, @dealloc и уведомление переднего плана вызывались одновременно из двух разных потоков, поэтому, когда метод выбора был выполнен в уведомлении, контроллер представления (без ссылок) уже был отмечен как или чтобы быть освобожденным.

Решение:

В @Carl предложил я добавил [[NSNotificationCenter defaultCenter] removeObserver:self]; за исключением того, не @dealloc, но на более раннем этапе, когда использование зрения контроллера было сделано. Я предполагаю, что делать это прямо перед тем, как будет работать повторная копирование.

+0

Если это ваше решение, вы должны отметить его как «принятый» ответ – ethyreal

1

Есть две проблем - ваше приложение делегат не управляет своей собственностью объектов правильно, и контроллер зрения не очистка после себя.

Каждый раз, когда вы выполняете код для создания экземпляра MyViewController, вы освобождаете владельца всех существующих контроллеров представлений, заменяя self.viewControllers новым экземпляром. Выделите это только один раз и добавьте и удалите объекты по мере необходимости. Кроме того, вы никогда не используете свое сильное свойство, только локальную переменную экземпляра с тем же именем. Вероятно, вы должны убедиться, что вы хотите, чтобы этот код повторялся снова и снова (я полагаю, что это так, учитывая описанные вами симптомы и информацию).

Кроме того, в MyViewController, осуществлять dealloc (или добавить к нему, если вы уже реализовали):

- (void)dealloc 
{ 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 
+0

Спасибо за ваш ответ. Я просто попытался использовать массив, потому что видел это в ответ. У моего фактического кода нет свойства viewControllers. У меня есть 1. @property (сильный, неатомный) MyViewController * myViewController; 2. self.myViewController = [storyBoard instantiateViewControllerWithIdentifier: @ "MyViewController"]; Я понимаю, что это повторно инициализирует представление каждый раз, когда он вызывается, но в противном случае мне придется сбросить все свойства представления. –

+0

@IsraelZalmanov OK, действительно ли реализовал dealloc помощь с вашей проблемой? –

+0

dealloc сам по себе не помог, но я установил точку останова в dealloc и увидел, что dealloc получает вызов после того, как приложение возвращается на передний план и без MyViewController * myViewController = [storyBoard instantiateViewControllerWithIdentifier: @ "MyViewController"]; (у меня тоже есть точка останова). Я также вижу, что это происходит, только когда MyViewController создается дважды (а затем во второй раз, когда он идет на bg и обратно, он падает). Я еще не уверен, что делать дальше. –

Смежные вопросы