当应用程序进入后台时,我的视图控制器被释放。

5 浏览
0 Comments

当应用程序进入后台时,我的视图控制器被释放。

我的视图控制器类在应用程序进入后台时被释放。我正在使用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];

0
0 Comments

问题的原因是,应用委托没有正确管理对象的所有权,同时视图控制器在应用进入后台后没有清理自己。

解决方法是,每次实例化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被实例化两次时(然后在第二次进入后台并返回时会崩溃),才会发生这种情况。我还不确定接下来该尝试什么。

0
0 Comments

问题:当应用程序进入后台时,我的视图控制器(My View Controller)被释放。

原因:每次调用`MyViewController *myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"];`时,`MyViewController`都会重新实例化。

使用ARC时,当应用程序进入前台时会进行一些清理工作。当应用程序从后台切换到前台时,后台通知和前台通知会同时从两个不同的线程中调用,因此当通知中的选择器方法执行时,已经将没有引用的视图控制器标记为或将要被释放。

解决方法:根据建议,我添加了`[[NSNotificationCenter defaultCenter] removeObserver:self];`,但不是在中,而是在视图控制器的使用完成之前的一个较早的时间点上。我猜在重新实例化之前这样做也可以起作用。

0