6

我正在启动这样的后台任务

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:YES?

如果是这样,为什么应用程序崩溃以及为什么 dispatch_async 解决了这个问题?

提前致谢!

4

1 回答 1

2

使用 performSelectorOnMainThread:withObject:waitUntilDone:YES 可能是线程死锁的原因。当前线程停止并等待。如果主线程没有及时完成选择器的执行,iOS 可能会因为占用主线程的时间超过允许的时间(通常为 10 秒,有时更短)而终止您的应用程序。

dispatch_async(dispatch_get_main_queue... 调用不会以这种方式阻塞。它总是将事件放入队列中并等待轮到它,当前线程继续进行而不会停止。

如果没有更多关于坠机性质的信息,很难说发生了什么。

于 2014-02-20T11:35:49.617 回答