2017-03-13 36 views
1

当我从我的按钮几次(如生气多次)调用此函数,然后我的应用程序崩溃,而不是只抛出异常,并忽略。Objective-C - 如何做异常捕获并避免应用程序崩溃?

如何在发生异常时忽略崩溃?

其中localView是UIView *localView

- (void)smallLocalView { 
    @try { 
    self.localView.backgroundColor = [UIColor blackColor]; 
    [self.localView.layer removeFromSuperlayer]; 
     //self.localView.opaque = NO; 
    } 
    @catch(NSException *exp) { 
     //NSLog(@">>> failed %@" , exp.reason); 
    NSLog(@"OK - but dont crash!!!"); 
    } 
    @finally { 
    NSLog(@"OK - but dont crash!!!"); 
    } 

} 

enter image description here

编辑:

enter image description here

+2

一般你不能赶上访问冲突,在这种特殊情况下,你可以'self.localView添加检查!= nil' – sage444

+0

我申请!=零,但仍然死机一样。 – YumYumYum

+0

嗯,好吧,当'self'或'localView'(或两者)为空时可能发生崩溃,请立即更新代码并立即崩溃 – sage444

回答

2

确保你是在主线程改变背景颜色时。

您可以在开头添加一个断言,这样,其他检查左侧的堆栈跟踪,当你为了在你哪个线程检查得到异常:

NSAssert([NSThread isMainThread]); 

而且,这取决于你从哪里拨打smallLocalView,这可能是因为你的视图没有加载/准备好。

- (void)smallLocalView { 
    if (!self.isViewLoaded) { 
     return; 
    } 
    ... 
} 
7

tl; dr一般来说,您不应该试图捕捉异常,您应该尝试修复根本原因。

有你感兴趣2种例外的。在你的图像中显示的第一种是系统异常。处理器遇到了一个问题,例如试图访问受保护的内存(通常通过尝试取消引用空指针来调用)。你无法捕捉到那种例外。操作系统将在您升级时终止您的程序。

的问题,顺便说一下,几乎可以肯定是由localView造成已提前释放,或者你访问它不是在主线程(根据埃德加的答案)。

另一种例外的是Objective-C的例外,这始终是编程上升。虽然你可以用@try { ... } @catch { ... }块来捕获这些数据,但一般情况下你不应该这样做。原因在于没有执行来使代码异常安全,所以异常可能会展开堆栈帧,其中资源需要解除分配或堆栈帧需要清理以保持数据结构的一致性。一旦抛出并捕获异常,就无法保证程序状态的逻辑一致性。你唯一的选择是尽可能干净地终止。

相关问题