2011-06-07 46 views
1

在我的iOS(iPhone/cocos2d)项目中,我发现我抛出自己的异常不会导致应用程序终止(他们只是导致当前函数退出,这会导致奇怪的半冻结行为)。例如,下面的代码导致系统崩溃:我的Objective-C异常不会导致我的应用程序终止,但苹果的做

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]' 

但是,如果我尝试为了引发一个异常(例如来自assert),除非我启用了“停止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块;任何人有想法?

回答

5

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

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

注意:不要使用异常的方式来控制程序流程,因为它们是非常昂贵在Objective-C升高时。

+0

嘿,谢谢你的回复。你知道,我没有想过在我的applicationDidFinishLaunching:方法中尝试使用这段代码,但它会按预期崩溃应用程序。然而,进一步进入应用程序(这是一个使用Cocos2d库的游戏),相同的异常什么也不做;我将不得不做更多的研究。 – 2011-06-27 05:37:28

+0

我还注意到Apple文档说:“Cocoa应用程序的主线程上的异常通常不会升至未捕获的异常处理程序的级别,因为全局应用程序对象会捕获所有这些异常。”很高兴知道,虽然再次,有时它确实奏效 - 我想这就是“典型”。 – 2011-06-27 05:53:59

+0

* ...他们是非常昂贵的......“在这种情况下,成本并不是一个问题,它们的投入并不是那么昂贵,其成本与抛出C++异常相同,真正的问题IMO是ObjC程序只是没有没有设计/编写来从异常中恢复,使用异常作为控制流通常会导致很多泄漏和其他类似的与清理相关的问题,在清理时不会发生。另一个例子:'@ synchronized'会正确解开并解锁,但我没有看到ObjC开发人员实际在清理时手动清除了其他锁定机制。 – justin 2012-10-31 19:06:44

相关问题