当应用程序进入后台时,我的视图控制器被释放。
当应用程序进入后台时,我的视图控制器被释放。
我的视图控制器类在应用程序进入后台时被释放。我正在使用ARC。
我有一个UIViewController,当应用程序变为活动状态并执行一个方法时,它会订阅通知。但是一旦应用程序在后台停留约30秒然后恢复,应用程序就会崩溃并显示“向已释放实例发送消息”。
启用僵尸对象后发现视图控制器本身是僵尸对象。
谢谢!
在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;
我尝试将视图控制器添加到一个数组中,并在AppDelegate中对数组进行强引用,但结果仍然相同:
@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];
问题的原因是,应用委托没有正确管理对象的所有权,同时视图控制器在应用进入后台后没有清理自己。
解决方法是,每次实例化MyViewController
时,都会通过用新实例替换self.viewControllers
释放所有现有视图控制器的所有权。应该只分配一次,并根据需要添加和删除对象。另外,你从未使用强引用属性,只使用了同名的局部实例变量。你应该确保你确实希望该代码一遍又一遍地运行(根据你描述的症状和信息,我假设它正在运行)。
此外,在MyViewController
中实现dealloc
方法(如果已经实现,请添加到其中):
- (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; }
谢谢你的回复。我尝试使用数组是因为我在一个回答中看到的。我的实际代码没有viewControllers
属性。我有以下两行代码:
1. (strong, nonatomic) MyViewController *myViewController; 2. self.myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"];
我理解每次调用这些代码时都会重新初始化视图,但否则,我将不得不重置视图的所有属性。
好的,实现dealloc
有助于解决你的问题吗?
只实现dealloc
没有帮助,但我在dealloc
中设置了断点,并观察到在应用返回前台后,dealloc
被调用,并且不会调用MyViewController *myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"];
(我在那里也设置了断点)。我还发现,只有当MyViewController
被实例化两次时(然后在第二次进入后台并返回时会崩溃),才会发生这种情况。我还不确定接下来该尝试什么。
问题:当应用程序进入后台时,我的视图控制器(My View Controller)被释放。
原因:每次调用`MyViewController *myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"];`时,`MyViewController`都会重新实例化。
使用ARC时,当应用程序进入前台时会进行一些清理工作。当应用程序从后台切换到前台时,后台通知和前台通知会同时从两个不同的线程中调用,因此当通知中的选择器方法执行时,已经将没有引用的视图控制器标记为或将要被释放。
解决方法:根据建议,我添加了`[[NSNotificationCenter defaultCenter] removeObserver:self];`,但不是在中,而是在视图控制器的使用完成之前的一个较早的时间点上。我猜在重新实例化之前这样做也可以起作用。