iOS:不会终止或处理许多异常

时间:2011-03-27 00:14:03

标签: iphone objective-c cocoa-touch exception

(编辑:当触摸屏幕时不会发生这种情况。如果程序最近没有启动,似乎会发生。会继续调查,但请回复您的想法。可能与this problem有关。

当触摸屏幕时,我的iPhone项目不会对NSExceptions 做任何事情,当它运行几秒钟时。

刚开始时,没关系。如果(例如)我在我的代码中导致异常:

NSException *e = [NSException
        exceptionWithName:@"Testing"
        reason:@"Testing exception handling"
        userInfo:nil];
@throw e;
if (touched) {
}

...然后异常按预期工作。如果我使用了NSSetUncaughtExceptionHandler,那么我的& uncaughtExceptionHandler会被调用;如果我没有,我得到SIGABRT并且程序终止。一切都好。

但是,如果我用以下代码替换它(如果只有touchesBegan触及的话是真的):

if (touched) {
    NSException *e = [NSException
            exceptionWithName:@"Testing"
            reason:@"Testing exception handling"
            userInfo:nil];
    @throw e;
}

...然后我的NSSetUncaughtExceptionHandler代码没有被调用,也没有收到SIGABRT信号。它似乎只是停止执行该运行循环&开始下一个。

如果你在那里设置一个断点,然后“跳过”或“进入”,那么它就会开始运行,就好像你已经点击继续(但没有运行该运行循环的其余部分)。

同样的事情发生在不同的班级。我没有可能劫持NSException的尝试/捕获。如果我做类似的事情,它的行为方式相同......

[[NSArray array] objectAtIndex:1];

......做例外。它在模拟器和设备中都是相同的。

请帮助例外获得他们应得的认可!


在回应bbum时,以下是上述第一种情况的回溯,其中异常按预期工作:

(gdb) BT
#0  -[Hud paintHudWithController:] (self=0x6475ee0, _cmd=0xbeb61, controller=0x686ac00) at /Users/mike/iPhone Dev/Parsec/Classes/Hud.m:2804
#1  0x00004f8e in -[ES1Renderer(Artist) paint] (self=0xa108a90, _cmd=0xc1b48) at /Users/mike/iPhone Dev/Parsec/Classes/ES1Renderer+Artist.m:92
#2  0x00003c22 in -[ES1Renderer render] (self=0xa108a90, _cmd=0x5f0dbb9) at /Users/mike/iPhone Dev/Parsec/Classes/ES1Renderer.m:81
#3  0x00003476 in -[EAGLView drawView:] (self=0xa103a70, _cmd=0xbe451, sender=0x64068a0) at /Users/mike/iPhone Dev/Parsec/Classes/EAGLView.m:79
#4  0x00c3c6a8 in CA::Display::DisplayLink::dispatch ()
#5  0x00c3c7ed in CA::Display::EmulatorDisplayLink::callback ()
#6  0x01494fe3 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ ()
#7  0x01496594 in __CFRunLoopDoTimer ()
#8  0x013f2cc9 in __CFRunLoopRun ()
#9  0x013f2240 in CFRunLoopRunSpecific ()
#10 0x013f2161 in CFRunLoopRunInMode ()
#11 0x000089e7 in -[Ticker tick] (self=0x686ac00, _cmd=0xbeb83) at /Users/mike/iPhone Dev/Parsec/Ticker.m:87
#12 0x00004e99 in -[ES1Renderer(Artist) paint] (self=0xa108a90, _cmd=0xc1b48) at /Users/mike/iPhone Dev/Parsec/Classes/ES1Renderer+Artist.m:67
#13 0x00003c22 in -[ES1Renderer render] (self=0xa108a90, _cmd=0x5f0dbb9) at /Users/mike/iPhone Dev/Parsec/Classes/ES1Renderer.m:81
#14 0x00003476 in -[EAGLView drawView:] (self=0xa103a70, _cmd=0xbe451, sender=0x0) at /Users/mike/iPhone Dev/Parsec/Classes/EAGLView.m:79
#15 0x000034ec in -[EAGLView layoutSubviews] (self=0xa103a70, _cmd=0x81b3de) at /Users/mike/iPhone Dev/Parsec/Classes/EAGLView.m:85
#16 0x00b80451 in -[CALayer layoutSublayers] ()
#17 0x00b8017c in CALayerLayoutIfNeeded ()
#18 0x00b7937c in CA::Context::commit_transaction ()
#19 0x00b790d0 in CA::Transaction::commit ()
#20 0x00ba97d5 in CA::Transaction::observer_callback ()
#21 0x01494fbb in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#22 0x0142a0e7 in __CFRunLoopDoObservers ()
#23 0x013f2bd7 in __CFRunLoopRun ()
#24 0x013f2240 in CFRunLoopRunSpecific ()
#25 0x013f2161 in CFRunLoopRunInMode ()
#26 0x01de8268 in GSEventRunModal ()
#27 0x01de832d in GSEventRun ()
#28 0x0041e42e in UIApplicationMain ()
#29 0x000024a4 in main (argc=1, argv=0xbffff040) at /Users/mike/iPhone Dev/Parsec/main.m:13

这是上面第二种情况的回溯,其中显然有异常吃掉:

(gdb) BT
#0  -[Hud paintHudWithController:] (self=0x6469710, _cmd=0xbeb61, controller=0x6855000) at /Users/mike/iPhone Dev/Parsec/Classes/Hud.m:2806
#1  0x00004a36 in -[ES1Renderer(Artist) paint] (self=0x7922720, _cmd=0xc1b48) at /Users/mike/iPhone Dev/Parsec/Classes/ES1Renderer+Artist.m:92
#2  0x000036ca in -[ES1Renderer render] (self=0x7922720, _cmd=0x5f0dbb9) at /Users/mike/iPhone Dev/Parsec/Classes/ES1Renderer.m:81
#3  0x00002f1e in -[EAGLView drawView:] (self=0x7907de0, _cmd=0xbe451, sender=0x7926cd0) at /Users/mike/iPhone Dev/Parsec/Classes/EAGLView.m:79
#4  0x00c3c6a8 in CA::Display::DisplayLink::dispatch ()
#5  0x00c3c7ed in CA::Display::EmulatorDisplayLink::callback ()
#6  0x01494fe3 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ ()
#7  0x01496594 in __CFRunLoopDoTimer ()
#8  0x013f2cc9 in __CFRunLoopRun ()
#9  0x013f2240 in CFRunLoopRunSpecific ()
#10 0x013f2161 in CFRunLoopRunInMode ()
#11 0x01de8268 in GSEventRunModal ()
#12 0x01de832d in GSEventRun ()
#13 0x0041e42e in UIApplicationMain ()
#14 0x00001f4c in main (argc=1, argv=0xbffff040) at /Users/mike/iPhone Dev/Parsec/main.m:13

5 个答案:

答案 0 :(得分:4)

几个星期前我在一个OpenGL项目中遇到了同样的事情。这是因为显示链接安装了顶级异常处理程序。不幸的是,除了在你的显示链接处理程序中安装你的OWN中级异常处理程序并在你捕获异常时执行abort()之外,没办法解决这个问题。

至少为我工作。

附录:刚发现Core Animation也安装了顶级异常处理程序。检查日志中的“CoreAnimation:忽略异常”。

答案 1 :(得分:3)

更有可能的是,跟踪触摸的任何模态事件循环都会吞噬异常。通过http://bugreporter.apple.com/提交错误。

通常,iOS中的控制流不应使用异常。例外将被视为不可恢复的错误。

这就是为什么这是一个错误;因为你已经正确推测异常应该杀死应用程序。

答案 2 :(得分:2)

Owerride应用程序方法reportExceptions @implementation MyApplication

-(void) reportExceptions (NSException *)e
{
   @try {
   // show u expression here, [e callStackTrace] [e reason].   
   }
   @catch (NSExpression *)ee {   
    // u can be wrong in try also :-).   
   }
}

不要忘记在plist Principal Class = MyApplication

中设置自定义应用程序子类

答案 3 :(得分:1)

这可能不是解决方案,但可能有助于找到一个。我的回答分为两部分:

1)试试看它是否有任何区别。

NSException *e = [NSException
            exceptionWithName:@"Testing"
            reason:@"Testing exception handling"
            userInfo:nil];

 if (touched) {
   @throw e; 
}

我看到的两个代码片段之间的唯一区别是,除了需要在if语句中抛出异常这一事实之外,NSException在{{}内声明1}}。

2)您是否尝试过此操作以检查在if内是否可以捕获异常?

if

或者试试看它是否与上面的代码不同。

@try {
  if (touched) {
    NSException *e = [NSException
            exceptionWithName:@"Testing"
            reason:@"Testing exception handling"
            userInfo:nil];
    @throw e;
  }
}
@catch (id anException) {
     NSLog(@"Exception: %@", [anException description]);
}

如果您发现任何有趣的内容,请告知我们(例如第2部分中的2个代码片段的工作方式不同)。当我了解异常以及如何捕捉它们时,它将对我有所帮助。最后,我必须为我正在进行的项目创建一个崩溃记者。

答案 4 :(得分:1)

请尽力保留您的观点。 [查看保留]