如何在swift中全局捕获未处理的异常?

时间:2016-02-10 14:50:43

标签: ios objective-c swift

我想在我的应用程序中处理一个全局处理程序中的每个单独的exeption。 我创建了一个objective-c头文件和实现文件,然后创建了桥接文件以访问swift代码中的objective-c代码。之后在AppDelegate中我设置了UncaughtExceptionHandler但处理程序没有调用。我做错了什么?

UncaughtExceptionHandler.h

#import <Foundation/Foundation.h>

volatile void exceptionHandler(NSException *exception);
extern NSUncaughtExceptionHandler *exceptionHandlerPtr;


@interface UncaughtExceptionHandler : NSObject

@end

UncaughtExceptionHandler.m

#import "UncaughtExceptionHandler.h"


@implementation UncaughtExceptionHandler

volatile void exceptionHandler(NSException *exception) {
    printf("TEST");
}

NSUncaughtExceptionHandler *exceptionHandlerPtr = &exceptionHandler;

@end

桥接-Header.h

#import "UncaughtExceptionHandler.h"

AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        NSSetUncaughtExceptionHandler(exceptionHandlerPtr)

        return true
    }

2 个答案:

答案 0 :(得分:3)

为什么你认为它没有被召唤?你是如何提出异常的?您可能会误解ObjC中的例外情况。例如,访问数组越界不是ObjC异常。

如果您的意思是&#34;可能导致应用程序崩溃的事情,&#34;那么写一个非常复杂的东西,你不应该试着自己写。你想使用PLCrashReporter之类的东西。即使您打算自己编写,也应该首先深入学习PLCrashReporter,以了解他们所做的一切。我提到它很复杂吗?非常小的错误(比如,尝试分配内存)会使程序死锁,导致CPU在紧密螺旋锁中升温(是的;有那个错误)。

直接在Swift代码中引发ObjC异常是不可能的,因此Swift错误无法导致调用此函数。它必须在ObjC中调用一些东西。

为&#34;处理设定正确的期望也很重要。&#34;通过&#34;处理&#34;你需要表示&#34;写下以后报告所需的最小状态,然后退出程序。&#34;如果通过&#34;处理&#34;你是说&#34;让我们回到一个我们不会崩溃的状态,&#34;这是不可能的。一旦在ObjC中抛出异常(无论是ObjC异常还是硬件异常),您都需要很快崩溃。这些情况无法恢复。 (这与C ++或Java完全不同,其中异常是错误处理的正常部分。在ObjC中它们不是。)这就是为什么NSSetUncaughtExceptionHandler被记录为:

  

设置顶级错误处理函数,您可以在程序终止前执行最后一分钟

答案 1 :(得分:0)

你做错的第一件事就是首先尝试这样做。假设我们讨论的是Objective-C异常,则会抛出它们来指示编程错误。你没有抓住它们。你让他们崩溃你的程序,然后你修复错误。

如果你在谈论Swift try / catch / throw,那就是错误处理的语法糖。如果你调用一个可以抛出的函数,你必须在那里捕获它。