在main中捕获NSException

时间:2014-05-12 19:59:01

标签: ios objective-c nsexception

我接手的iOS应用程序有一种处理NSExceptions的方式与我之前看到的不同,并想知道它为什么现在不起作用。

在main.m文件中,旧开发人员有这样的逻辑:

int main(int argc, char *argv[])
{
    @autoreleasepool {
        int retVal = 0;
        @try {
            retVal =  UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
        @catch (NSException *exception) {
            //
            //Logic to save Exception in DataStore
            //
            NSLog(@"Exception - %@",[exception description]);
            exit(EXIT_FAILURE);
        }
        return retVal;
    }
}

当应用程序再次启动时,您会收到向我们发送异常的提示,如果您确认将其发送到我们的服务器。

我最近推出了针对应用程序的iOS 7更优化的更新,并注意到我不再从崩溃的应用程序中获得任何这些错误报告。

所以我通过以下代码测试了它,我知道这个代码被称为:

NSArray *array = [NSArray new];

id object = [array objectAtIndex:4];

我收到的是:

2014-05-12 14:55:57.575 APPNAME[17989:60b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 4 beyond bounds for empty array'
*** First throw call stack:
(0x18ab0b09c 0x196a89d78 0x18aa0c680 0x10007f498 0x18d9e02c0 0x18da997d0 0x18da996cc 0x18da98ba0
 0x18da98840 0x18da98564 0x18da984e4 0x18d9dad78 0x18d5d70cc 0x18d5d1c94 0x18d5d1b4c 
 0x18d5d13d4 0x18d5d1178 0x18d5caa30 0x18aacb7e0 0x18aac8a68 0x18aac8df4 0x18aa09b38 
 0x19042f830 0x18da480e8 0x100036b98 0x197073aa0)
libc++abi.dylib: terminating with uncaught exception of type NSException

正如您所看到的,异常未被记录或保存,而是完全未被捕获。

2个问题:

  1. 这是不好的做法吗?我认为不是,但我是小伙伴。开发人员,并不确定,如果有更好的方法来做这个没有第三方服务?

  2. 您是否知道iOS 7中的任何更改会影响此(UNTOUCHED)逻辑?

2 个答案:

答案 0 :(得分:10)

  

这是不好的做法吗?我不认为这是,但我是一个小伙伴。开发者和   不确定,如果有更好的方法做到这一点w / o第三   派对服务?

是的,这是不好的做法。 UIApplicationMain()是一个黑洞;一旦将控制传递给该函数,就不可能再次调用main()中该调用之外的任何代码。

这也是一个天真的实施;它比stdout记录的信息少于正常的异常处理机制(这是你看到的输出)。它隐藏了对调试有用的信息,并且可能绕过标准的崩溃报告机制。

请注意,还有一个全局未处理的异常处理挂钩。我不建议使用它,但确实存在。

  

你知道iOS 7中会有什么变化会影响这个(UNTOUCHED)   逻辑?

没有离开,但我没看过。尽管如此,UIApplicationMain()是一个黑洞;它通常不会回归。

答案 1 :(得分:5)

根据Exception Programming Topics,您可以使用 NSSetUncaughtExceptionHandler 函数来处理未捕获的异常。请尝试以下代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSSetUncaughtExceptionHandler(handleUncaughtException);
    @throw [NSException exceptionWithName:NSGenericException
                                   reason:@"Test uncaught exception handling"
                                 userInfo:nil];

    return YES;
}

void handleUncaughtException(NSException *exception)
{
    NSLog(@"Exception - %@",[exception description]);
    exit(EXIT_FAILURE);
}