我正在启动后台任务,如下所示:
UIApplication* application = [UIApplication sharedApplication];
_backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^
{
[application endBackgroundTask:_backgroundTask];
_backgroundTask = UIBackgroundTaskInvalid;
}];
该应用程序已发送至后台,一切正常。
一段时间后,某些条件得到满足,一些对象最终执行此代码:
[self performSelectorOnMainThread:@selector(doSomething) withObject:nil waitUntilDone:YES];
此时,应用程序崩溃了!
请注意,在这种特殊情况下,对象正在主线程中执行。
我用以下代码替换了上面的代码:
dispatch_async(dispatch_get_main_queue(), ^{
[self doSomething];
});
一切似乎都没问题,崩溃消失了。
我能想象的是,waitUntilDone:YES可能与众不同,但这只是我的直觉。
我的问题是:
是否允许使用performSelectorOnMainThread:withObject:waitUntilDone:应用程序在后台运行时是?
如果是这种情况,为什么应用程序崩溃以及dispatch_async解决问题的原因是什么?
提前致谢!
答案 0 :(得分:2)
使用performSelectorOnMainThread:withObject:waitUntilDone:YES可能是导致线程死锁的原因。当前线程停止并等待。如果主线程没有及时完成选择器的执行,那么iOS可以杀死你的应用程序,使主线程占用超过允许的时间(通常为10秒,有时更少。)
dispatch_async(dispatch_get_main_queue ...调用不会阻塞这种方式。它总是将一个事件放入队列并等待其轮流,当前线程继续运行而不停止。
如果没有关于崩溃性质的更多信息,很难说发生了什么。