当应用程序进入后台时,我的视图控制器将被取消分配

时间:2013-03-20 15:58:22

标签: iphone ios objective-c automatic-ref-counting

当应用程序转到后台时,我的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];

2 个答案:

答案 0 :(得分:1)

这里有两个问题 - 你的app委托没有正确管理对象的所有权,而且视图控制器没有自行清理。

每次执行代码以实例化MyViewController时,都会通过将self.viewControllers替换为新实例来释放所有现有视图控制器的所有权。仅分配一次,并根据需要添加和删除对象。此外,您永远不会使用强属性,只使用同名的本地实例变量。您可能确实应该确保您希望此代码一遍又一遍地运行(我假设它是,根据您描述的症状和信息)。

此外,在MyViewController中,实施dealloc(如果已经实施,则添加到其中):

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

答案 1 :(得分:0)

问题:

    每次调用MyViewController时都会重新实例化
  1. MyViewController *myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"];

  2. 使用ARC,看起来当应用程序到达前台时,会进行一些清理工作。

  3. 当应用程序移动到前台时,@dealloc和前台通知从两个不同的线程同时被调用,因此当在通知上执行选择器方法时,(无引用)视图控制器已被标记为或将被解除分配。

  4. 解决方案:

    正如@Carl建议我添加[[NSNotificationCenter defaultCenter] removeObserver:self];,但@dealloc除外,但在视图控制器使用完成时更早。我认为在重新实例化之前做正确的事情也可以。