当应用程序转到后台时,我的View Controller类会被释放。我正在使用ARC。
我有一个UIViewController,当应用程序变为活动状态并执行方法时,它会订阅通知。但是一旦应用程序在后台运行大约30秒然后恢复,应用程序就会崩溃并将“消息发送到解除分配的实例”。
启用Zombie对象会显示View Controller本身就是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)
这里有两个问题 - 你的app委托没有正确管理对象的所有权,而且视图控制器没有自行清理。
每次执行代码以实例化MyViewController
时,都会通过将self.viewControllers
替换为新实例来释放所有现有视图控制器的所有权。仅分配一次,并根据需要添加和删除对象。此外,您永远不会使用强属性,只使用同名的本地实例变量。您可能确实应该确保您希望此代码一遍又一遍地运行(我假设它是,根据您描述的症状和信息)。
此外,在MyViewController
中,实施dealloc
(如果已经实施,则添加到其中):
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
答案 1 :(得分:0)
问题:
MyViewController
时都会重新实例化 MyViewController *myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"];
。
使用ARC,看起来当应用程序到达前台时,会进行一些清理工作。
当应用程序移动到前台时,@dealloc
和前台通知从两个不同的线程同时被调用,因此当在通知上执行选择器方法时,(无引用)视图控制器已被标记为或将被解除分配。
解决方案:
正如@Carl建议我添加[[NSNotificationCenter defaultCenter] removeObserver:self];
,但@dealloc
除外,但在视图控制器使用完成时更早。我认为在重新实例化之前做正确的事情也可以。