简体   繁体   English

当应用程序进入后台时,我的View Controller会被释放

[英]My View Controller gets deallocated when the app goes to the background

My View Controller class gets deallocated when the app goes to the background. 当应用程序进入后台时,我的View Controller类将被释放。 I'm using ARC. 我正在使用ARC。

I have a UIViewController that subscribes to a notifications when the app becomes active and executes a method. 我有一个UIViewController,当应用程序变为活动状态并执行一个方法时,它会订阅通知。 But once the app is about 30 secs in the background and then resumes, the app crashes with "message sent to deallocated instance". 但是,一旦应用程序在后台运行约30秒钟,然后恢复运行,该应用程序就会崩溃,并显示“发送到已释放实例的消息”。

Enabling Zombie objects shows that the View Controller itself is the Zombie. 启用Zombie对象将显示视图控制器本身就是Zombie。

Thank you! 谢谢!

Instantiation of my view controller (in AppDelegate): 我的视图控制器的实例化(在AppDelegate中):

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

The foreground notification in AppDelegate: AppDelegate中的前台通知:

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

The foreground notification in the view controller: 视图控制器中的前台通知:

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

I tried creating a strong reference in the AppDelegate, but the view controller still gets deallocated: 我尝试在AppDelegate中创建一个强引用,但是视图控制器仍然被释放:

@property (strong, nonatomic) MyViewController *myViewController;

I tried adding the view controller to an array and have a strong reference to the array in the AppDelegae, but still I get the same results: 我尝试将视图控制器添加到数组中,并在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];

There are two issues here - your app delegate is not managing its ownership of objects correctly, and the view controller is not cleaning up after itself. 这里有两个问题-您的应用程序委托未正确管理其对象所有权,视图控制器本身未清除。

Every time you execute the code to instantiate an MyViewController , you release ownership of all existing view controllers by replacing self.viewControllers with a new instance. 每次执行代码以实例化MyViewController ,都可以通过将self.viewControllers替换为新实例来释放所有现有视图控制器的所有权。 Only allocate that once, and add and remove objects as needed. 仅分配一次,并根据需要添加和删除对象。 Also, you never use your strong property, only a local instance variable of the same name. 另外,您永远不要使用您的Strong属性,而只能使用同名的本地实例变量。 You should probably actually make sure that you want this code to run over and over (I assume that it is, given the symptoms and information you describe). 您可能实际上应该确保您希望该代码反复运行(考虑到您描述的症状和信息,我认为是这样)。

Also, in MyViewController , implement dealloc (or add to it if you have implemented already): 另外,在MyViewController ,实现dealloc (如果已经实现,则添加到它):

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

The issue: 问题:

  1. MyViewController was re-instantiated every time MyViewController *myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"]; MyViewController被重新实例化每次MyViewController *myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"]; was called. 被称为。

  2. Using ARC, it looks like when the app goes to the foreground, some cleaning is done. 使用ARC,当应用程序进入前台时,看起来已经完成了一些清理工作。

  3. When the app was moved to the foreground, @dealloc and the foreground notification were called simultaneously from two different threads, so when the selector method was executed on the notification, the (no references) view controller was already marked as or to-be deallocated. 当应用程序移至前台时,从两个不同的线程同时调用@dealloc和前台通知,因此,在通知上执行选择器方法时,(无引用)视图控制器已被标记为或将被释放。

The solution: 解决方案:

As @Carl suggested I added [[NSNotificationCenter defaultCenter] removeObserver:self]; 正如@Carl所建议的,我添加了[[NSNotificationCenter defaultCenter] removeObserver:self]; except not in @dealloc , but at an earlier point when the view controller usage was done. 除了不在@dealloc ,而是在较早的时候完成视图控制器的使用。 I assume doing it right before re-instantiating would work as well. 我认为在重新实例化之前也可以这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当应用程序进入后台时,MPMoviePlayerViewController消失 - MPMoviePlayerViewController gets dissmiss when app goes background 当应用程序进入后台并返回时,我的NSRunLoop和计时器会发生什么? - What happens to my NSRunLoop and timer when the app goes into background and returns? 当呈现为模态视图控制器时,ARC UINavigationController堆栈未被释放 - ARC UINavigationController stack not getting deallocated when presented as modal view controller 根视图控制器已释放,因此如何保留它或将其再次添加到导航控制器中 - Root View controller is deallocated so how do I retain it or add it to my navigation controller again 当应用程序转到后台时,AVAudioPlayer无法播放 - AVAudioPlayer does not play when app goes to background 当应用程序进入后台时,网络连接正在丢失 - Network connection is losing when the app goes to the background 当应用程序进入后台时关闭弹出窗口 - Dismiss popover when app goes in background 应用程序进入后台时的内存占用量 - Memory footprint when app goes to the background 当应用程序进入后台时如何运行NSThread - how to run NSThread when app goes to background 进入后台模式时,如何在应用中更新位置管理器和计时器? - How can i update location manager and a timer in my app when it goes to background mode?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM