iOS:后台线程异常没有崩溃

时间:2013-01-12 22:30:05

标签: ios multithreading exception exception-handling abort

我没有找到符合我经验的文档。

我想要的是在后台线程中处理Uncaught-Exceptions的好方法。这种“方式”应该让应用程序崩溃,但在崩溃之前执行一些非常基本的操作(例如,将值保存到UserDefaults,以便可以在下次启动时检查;以及日志记录)。

在主线程上,我只是设置了一个 uncaughtExceptionHanlder ,这很好用。但是,在后台线程上 - 在NSOperationQueue上作为NSOperation执行 - 任何异常都会发生但不会退出应用程序:崩溃。该应用程序继续以损坏的状态运行。

然而,线程编程指南指出:

  

设置异常处理程序如果您的应用程序捕获并且   处理异常,你的线程代码应准备好抓住任何东西   可能发生的异常。虽然最好处理异常   在他们可能发生的地方,没有抓到抛出   线程中的异常会导致应用程序退出。安装一个   你的线程入口例程中的最终try / catch允许你捕获任何   未知的例外并提供适当的回应。

一个有效的方法(下面)是使用try / catch嵌入线程调用方法,如果是异常,则记录然后调用abort()。但这不是最好的方法。我想将异常发送到主线程并让它由未捕获的异常处理程序处理。 有没有人这样做过?

- (void)threadMethod
{
    @try
    {
        NSArray* aTest = [NSArray array];
        [aTest objectAtIndex:10];
    }
    @catch (NSException* e)
    {
        // Save to state to User Defaults.
        // Log any needed info.

        abort();
    }
    @finally
    {

    }
}

仅供参考:我使用XCode 4.5 SDK在iOS6上运行。

2 个答案:

答案 0 :(得分:6)

  1. NSOperationQueue运行的主题由libdispatch管理,该异常会捕获异常并调用terminate,退出应用。如果你看到不同的行为,那你就已经做错了。
  2. 在异常之后将数据保存到NSUserDefaults是一个不确定的主张;因为Cocoa只将异常视为程序员错误,所以一旦被抛出,它就不会试图让自己处于可用状态。简而言之,您应该像处理“真正的”崩溃一样对待它,就好像只有异步信号安全的API可用。任何Objective-C都会在这方面自动退出。
  3. 您的问题表明您正在尝试进行崩溃报告。我会为此目的推荐崩溃报告解决方案,例如PLCrashReporter。还有许多嵌入崩溃报告的分析和分发服务,包括HockeyAppCrashlyticsTestFlightQuincyKit。还有其他人,哪一个适合你,取决于你的需要。所有这些都将处理安全处理崩溃和异常所涉及的所有棘手问题,并在以后保存数据,而不必担心任何问题。

答案 1 :(得分:0)

对于你正在做的事情,我相信你需要在你的主线程中检查你的第二个线程中发生的事情。由于您无法实际联系主线程并从后台线程触发事件,因此您很可能会在主线程中写入一些内容,每隔一段时间检查一次。也就是说,您可以使用NSNotificationCenter,并且当从后台线程抛出异常时,主线程会触发一个事件。祝你好运。