【问题标题】:My Objective-C exceptions don't cause my app to terminate, but Apple's do我的 Objective-C 异常不会导致我的应用程序终止,但 Apple 会
【发布时间】:2011-06-07 20:38:20
【问题描述】:

在我的 iOS (iPhone/cocos2d) 项目中,我发现自己抛出的异常不会导致应用程序终止(它们只会导致当前函数退出,从而导致奇怪的半冻结行为)。例如,以下代码会导致崩溃:

NSArray* testArray = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
[testArray objectAtIndex:400];

当我运行该代码时,正如我所料,我在控制台中得到以下信息:

2011-06-07 12:55:20.421 mansion-iphone[38184:207] *** Terminating app due to
    uncaught exception 'NSRangeException', reason: '*** -[NSArray
    objectAtIndex:]: index 400 beyond bounds [0 .. 2]'

但是,如果我尝试引发异常(例如,从断言),除非我启用了“停止 Objective-C 异常”,否则我会半冻结。这对我来说很好,但是当我的测试人员报告问题时会导致问题——因为应用程序没有崩溃,他们没有崩溃日志可以发送给我。下面是一个不起作用的异常示例:

NSException* e = [NSException exceptionWithName:NSInternalInconsistencyException 
        reason:[NSString stringWithFormat:@"%s %@", __PRETTY_FUNCTION__,
        [NSString stringWithFormat:@"Invalid argument"]] userInfo:nil];
[e raise];

关闭“在 Objective-C 异常时停止”,这甚至不会导致向控制台发送消息——使用 NSAssert 反而会给我一个控制台消息,但仍然没有停止。因此,看起来 Cocoa 类生成的异常行为正确,但源自我的代码的异常却不是。

我检查了我的代码和 cocos2d 并没有找到任何似乎可以防止异常的 @try 块;有人有想法吗?

【问题讨论】:

    标签: iphone objective-c ios exception


    【解决方案1】:

    自定义异常应该与其他异常一样工作,并且我能够在我自己的测试应用程序中验证这一点。需要检查的一些事项:

    1. 确保没有调用NSSetUnhandledExceptionHandler,以捕获所有未处理的异常。
    2. 尝试在调试器之外运行您的应用程序。
      • 我在上面测试了您的代码,当 NSRangeException 或自定义 NSException 被引发但未处理时,我的应用程序按预期终止。
    3. 尝试在别处引发异常以验证它是否正常工作,例如 main()。

    注意:不要使用异常来控制程序流程,因为它们在 Objective-C 中引发时非常昂贵。

    【讨论】:

    • 您好,谢谢您的回复。你知道,我没有想过在我的 applicationDidFinishLaunching: 方法中尝试该代码块,但它会按预期使应用程序崩溃。然而,进一步进入应用程序(这是一个使用 Cocos2d 库的游戏),同样的异常没有任何作用;我必须做更多的研究。
    • 我还注意到 Apple 文档这样说:“Cocoa 应用程序主线程上的异常通常不会上升到未捕获异常处理程序的级别,因为全局应用程序对象会捕获所有此类异常。 "很高兴知道,虽然有时它确实有效——我想这是“典型的”。
    • *... 它们非常昂贵..." 在这种情况下,成本不是问题。抛出它们真的没有那么昂贵。成本与抛出 C++ 异常相同。真正的问题IMO 是 ObjC 程序不是为了从异常中恢复而设计/编写的。使用异常作为控制流通常会导致许多泄漏和其他与清理相关的类似问题在展开时不会发生。另一个例子:@synchronized 会正确展开并且解锁,但我只是没有看到 ObjC 开发人员在展开时实际上手动清理了其他锁定机制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多