在Swift中未捕获的错误/exception处理
我知道在Cocoa中有一个UncaughtExceptionHandler ,但是我正在为Swift寻找同样的东西。 即每当在应用程序中出现任何错误/exception(由于任何错误而不在本地捕获)时,它应该一直冒泡到顶层应用程序对象,我应该能够适当地处理它并适当地响应用户。
Android有它。 Flex有它。 Java有它。 想知道为什么Swift缺less这个关键function。
Swift没有捕获所有任意运行时exception的机制。 原因解释在
- [swift-users]“商业应用市场”的火焰
在swift-users邮件列表上。 提取:
Swift有意识地select不包含通过任意堆栈框架抛出的exception,这不是因为技术上不可行,而是因为它的devise者认为成本太高。
问题是这样的:如果一段代码由于错误而要提早退出,那么它必须被写入来处理提前退出。 否则,它会行事不端 – 无法释放内存,无法closures文件句柄/套接字/数据库连接/任何,无法释放锁等。在像Java这样的语言中,编写真正的exception安全的代码需要大量的try / finally块。 这就是为什么没有人这样做。 他们判断他们可能看到哪些exception以及哪些资源可能泄露,并且只保护他们的代码免受这些特定的预期条件的影响。 然后发生一些不可预见的事情,他们的计划就会中断。
在像Swift这样的引用计数语言中,这更糟,因为在exception情况下正确平衡引用计数基本上要求每个函数都包含一个隐式finally块来平衡所有保留计数。 这意味着编译器必须生成很多额外的代码,否则某些调用会引发exception。 绝大多数的代码是从来没有使用过,但它必须在那里,膨胀的过程。
由于这些问题,Swiftselect不支持传统的例外; 相反,它只允许你在特殊标记的代码区域抛出错误。 但是作为一个必然结果,这意味着如果代码中的某些东西真的出错了,那么所有可以防止灾难的事情都会崩溃。 而目前,唯一可能导致整个过程崩溃的是
有关更多信息,请参阅
- error handling理由和build议
这是我用来logging所有exception/错误的代码。 Log.error(with:)
是一个自定义函数,用于存储堆栈跟踪以及其他信息。 Thread.callStackSymbols
是一个string数组,代表堆栈跟踪。
NSSetUncaughtExceptionHandler { (exception) in Log.error(with: Thread.callStackSymbols) } signal(SIGABRT) { (_) in Log.error(with: Thread.callStackSymbols) } signal(SIGILL) { (_) in Log.error(with: Thread.callStackSymbols) } signal(SIGSEGV) { (_) in Log.error(with: Thread.callStackSymbols) } signal(SIGFPE) { (_) in Log.error(with: Thread.callStackSymbols) } signal(SIGBUS) { (_) in Log.error(with: Thread.callStackSymbols) } signal(SIGPIPE) { (_) in Log.error(with: Thread.callStackSymbols) }