7

我还没有找到与我的经验一致的文档。

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

在主线程上,我只是设置了一个uncaughtExceptionHanlder并且工作正常。但是,在后台线程上 - 作为 NSOperationQueue 上的 NSOperation 执行 - 任何异常正在发生但未退出应用程序:Crashing。该应用程序继续在损坏的状态下运行。

但是,线程编程指南指出:

设置异常处理程序 如果您的应用程序捕获并处理异常,您的线程代码应该准备好捕获任何可能发生的异常。尽管最好在可能发生的地方处理异常,但未能在线程中捕获抛出的异常会导致您的应用程序退出。在你的线程入口例程中安装一个最终的 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
    {

    }
}

仅供参考:我在 iOS6 上运行,带有 XCode 4.5 SDK。

4

2 回答 2

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

对于您正在做的事情,我相信您将需要在主线程中检查第二个线程中发生的事情的代码。由于您无法实际联系主线程并从后台线程触发事件,您很可能会被卡在您的主线程中编写一些不时检查的内容。也就是说,您可能可以使用 NSNotificationCenter 并让主线程在后台线程抛出异常时触发一个事件。祝你好运。

于 2013-01-13T01:11:10.523 回答