Objective-C - 如何做异常捕获并避免让应用程序崩溃?

时间:2017-03-13 10:37:57

标签: ios objective-c uiview

当我从我的按钮调用此函数几次时(比如疯了几次),然后我的应用程序崩溃而不是抛出异常并忽略。

如果发生异常,你怎么忽略崩溃?

其中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 个答案:

答案 0 :(得分:7)

tl; dr一般情况下,您不应该尝试捕获异常,您应该尝试修复根本原因。

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

顺便提一下,这个问题几乎可以肯定是因为localView过早被解除分配,或者你可能不是在主线程上访问它(根据Edgar的回答)。

另一种异常是Objective-C异常,它总是以编程方式引发。虽然你可以用@try { ... } @catch { ... }块来捕获它们,但一般情况下你不应该这样做。原因是没有强制使代码异常安全,因此异常可能会解除需要释放资源的堆栈帧或需要清理以保持数据结构一致的堆栈帧。抛出并捕获异常后,您无法保证程序状态的逻辑一致性。您唯一真正的选择是尽可能干净地终止。

答案 1 :(得分:2)

确保在更改背景颜色时位于主线程上。

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

NSAssert([NSThread isMainThread]);

此外,根据您从smallLocalView调用的位置,您的视图可能无法加载/准备好。

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