Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone iOS:won';t终止或处理许多异常_Iphone_Objective C_Cocoa Touch_Exception - Fatal编程技术网

Iphone iOS:won';t终止或处理许多异常

Iphone iOS:won';t终止或处理许多异常,iphone,objective-c,cocoa-touch,exception,Iphone,Objective C,Cocoa Touch,Exception,(编辑:不仅仅发生在触摸屏幕时。如果程序最近未启动,则似乎会发生。我们将继续调查,但请给出您的想法。可能与此相关) 我的iPhone项目在运行几秒钟后触摸屏幕时,不会对NSExceptions执行任何操作 刚开始的时候,一切都很好。如果(例如)我在此处的代码中导致异常: NSException *e = [NSException exceptionWithName:@"Testing" reason:@"Testing exception handling"

(编辑:不仅仅发生在触摸屏幕时。如果程序最近未启动,则似乎会发生。我们将继续调查,但请给出您的想法。可能与此相关)

我的iPhone项目在运行几秒钟后触摸屏幕时,不会对NSExceptions执行任何操作

刚开始的时候,一切都很好。如果(例如)我在此处的代码中导致异常:

NSException *e = [NSException
        exceptionWithName:@"Testing"
        reason:@"Testing exception handling"
        userInfo:nil];
@throw e;
if (touched) {
}
…然后异常会按预期工作。如果我使用了NSSetUncaughtExceptionHandler,则调用我的&uncaughtExceptionHandler;如果我没有,我得到SIGABRT,程序终止。一切都好

但是如果我用以下代码替换它(如果刚刚有一个touchesbeated,那么touched是真的):

…然后不会调用my 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

更可能的是,异常被跟踪触摸的任何模态事件循环所吞噬。通过提交一个bug

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


这就是为什么这是一个错误;正如您正确猜测的那样,异常会导致应用程序死亡。

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

1) 试试这个,看看有没有什么不同

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

 if (touched) {
   @throw e; 
}
除了需要在
if
语句中抛出异常之外,我看到的两个代码片段之间的唯一区别是
NSException
是在
if
语句中声明的

2) 您是否尝试过这样做,以检查在
if
中抛出异常时是否能够捕获异常

@try {
  if (touched) {
    NSException *e = [NSException
            exceptionWithName:@"Testing"
            reason:@"Testing exception handling"
            userInfo:nil];
    @throw e;
  }
}
@catch (id anException) {
     NSLog(@"Exception: %@", [anException description]);
}
或者尝试一下,看看它的工作原理是否与上面的代码不同

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

如果您发现任何有趣的东西(如第2部分的2个代码片段工作方式不同),请告诉我。它将帮助我了解异常以及如何捕获它们。最后,我必须为我正在进行的项目创建一个崩溃报告程序。

请尝试强制保留您的视图。
[查看保留]

删除应用程序方法报告异常 @实现我的应用程序

-(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中设置自定义应用程序子类

几周前,我在OpenGL项目中遇到了同样的问题。这是因为显示链接安装了顶级异常处理程序。不幸的是,除了在显示链接处理程序中安装您自己的中级异常处理程序,并在捕获异常时在其中执行abort()之外,没有其他方法可以解决这个问题

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


附录:刚刚发现的核心动画还安装了一个顶级异常处理程序。检查日志中的“CoreAnimation:忽略异常”。

别担心,我从来不会将iOS异常用于控制流。:)我将捕获它并将其记录到分析服务器,然后重新抛出它以终止应用程序。这个答案不是它(请参见编辑的问题),尽管异常可能被其他东西吃掉。不过谢谢。:)将@throw的回溯贴在异常被吃掉的地方。好主意。在主帖子中添加了两个回溯。例外是被一个grue吃掉。我同意@bbum;这显然像是某个系统框架中的一个bug。包括一个带有两个按钮的测试项目,显示两种情况。有什么方法可以绕过它吗?除了检查上一个周期是否没有结束,如果是的话,记录它&halt(这不会提供太多有用的信息,但至少可以防止由于忽略异常和程序流混乱而可能发生的最有可能的损坏)。你有没有为此提交过错误?答案是什么?看史蒂文·克莱默的答案。看起来这是一个“功能”而不是一个bug。所有这些?这个问题贯穿整个项目。这怎么能解决被吃掉的例外情况呢?我指的只是一接触就打破的观点。。这一次试一试。视图的过度发布会导致异常被吃掉吗?好啊尝试保留EAGLView,没有效果,但是+1用于尝试:)1)像我的第二个案例一样,吃掉异常。2) 两个代码片段都捕获@catch中的异常。看起来它被抛出了,但是在程序停止之前,它被吃掉了。希望在此之前我能在某个有用的地方捕捉到异常。谢谢:)谢谢,这就解释了。对不起,我没有太多的经验工程显示链接的东西。。。我应该在EAGLView的drawView中试一试吗?嘿,迈克,你能赏金吗?是的,您的异常处理程序将出现在-[EAGLView drawView:]尝试一些温柔,正如Otis所说(如果这个晦涩难懂的流行音乐引用没有传到英国,那么很抱歉)是的,我们也收到了那些赏金广告:)