【问题标题】:iOS : Background Thread Exceptions Not CrashingiOS:后台线程异常不会崩溃
【发布时间】:2012-12-27 05:50:11
【问题描述】:

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

我想要的是一种在后台线程中处理未捕获异常的好方法。这种“方式”应该让应用程序崩溃,但在崩溃之前执行一些非常基本的操作(例如,将值保存到 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
    {

    }
}

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

【问题讨论】:

    标签: ios multithreading exception exception-handling abort


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

    【讨论】:

    • 这不是崩溃报告的问题。在崩溃的情况下,我想存储用于下次启动的状态信息。
    • 顺便说一句,我想说你最好的办法是使用简单的 POSIX API 以尽可能简单的格式将数据写入文件。再次,我必须强调任何 Objective-C 在异常即将使您的应用程序崩溃时都是不安全的;一切都处于未知状态。一个非常快速的,我头脑中的例子可能是:int fd = open(UTF8StringOfDocumentsDirectoryPlusFileNameSavedAtAppStartup, O_WRONLY | O_CREAT | O_TRUNC); if (fd != -1) { write(fd, "crashed", sizeof("crashed") - 1); close(fd); }
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2019-03-29
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      • 1970-01-01
      • 1970-01-01
      • 2014-05-23
      • 1970-01-01
      • 2017-04-15
      相关资源
      最近更新 更多