【问题标题】:Uncaught exception handler not called未调用未捕获的异常处理程序
【发布时间】:2012-03-21 02:41:02
【问题描述】:

我正在尝试在我的 Mac 应用程序上捕获异常,以便将它们记录在自定义日志文件中。我正在实现这样的异常处理程序:

void uncaughtExceptionHandler(NSException *exception) {
    NSLog(@"It Works!");
}

我将它设置在我的-applicationDidFinishLaunching: 方法中,如下所示:

NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);

然后我引发一个异常来测试它:

[[NSArray arrayWithObject:@"object"] objectAtIndex:1];

异常被记录到控制台,但我的异常处理程序没有被调用。

有什么想法吗?

【问题讨论】:

    标签: objective-c macos cocoa exception-handling foundation


    【解决方案1】:

    解决方案是使用ExceptionHandling 框架。我是这样做的:

    -applicationDidFinishLaunching:

    [[NSExceptionHandler defaultExceptionHandler] setExceptionHandlingMask:NSLogAndHandleEveryExceptionMask];
    [[NSExceptionHandler defaultExceptionHandler] setDelegate:self];
    

    然后在我的 App Delegate 类中,我实现了两个委托方法,

    - (BOOL)exceptionHandler:(NSExceptionHandler *)sender shouldLogException:(NSException *)exception mask:(NSUInteger)aMask
    - (BOOL)exceptionHandler:(NSExceptionHandler *)sender shouldHandleException:(NSException *)exception mask:(NSUInteger)aMask
    

    现在我可以捕获所有异常了!

    【讨论】:

      【解决方案2】:

      AppKit 在首先捕获异常的主线程上有自己的高级异常处理程序。您可以继承 NSApplication 并覆盖 -reportException: 以获得使用它的机会。

      不过,您的异常处理程序仍可能在其他线程上被调用。

      参考:Tim Wood's message on macosx-dev back in 1999

      【讨论】:

      • 我试过了,但我仍然没有发现异常。 -reportException: 永远不会被调用。如果在-applicationDidFinishLaunching: 中引发了异常,不应该调用它吗?这不是在主线程上运行的吗?
      • 是的,-applicationDidFinishLaunching: 在主线程上被调用。你确定你的NSApplication 子类正在被使用吗?您需要在 Info.plist 的键 NSPrincipalClass 下指定其类名。
      • 是的,我确定。 [NSApp class]; 返回我的子类。
      • 我也尝试过使用 ExceptionHandling.framework,但没有调用委托方法。
      • 我想通了,我在 +initialize 而不是 -applicationDidFinishLaunching: 中设置了 ExceptionHandling 委托。它现在正在工作。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-02
      • 2018-06-14
      • 2011-09-16
      • 2018-05-30
      • 2011-05-20
      • 1970-01-01
      相关资源
      最近更新 更多