iOS中的 uncaught exception 主要有哪些

iOS 中的错误分为 NSError 和 NSException,其中NSError用于可恢复的错误,而NSException则是不可恢复的错误,对于NSException我们可以通过NSSetUncaughtExceptionHandler来进行崩溃的捕获获取,那么常见的 NSException 有哪些呢?

  • 数组越界访问
NSArray *array = @[@"2"];
NSString *aa = array[2];
//	对应崩溃错误信息
//	Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 0]'
  • KVC赋值给一个没有定义的key
[[UIViewController new] setValue:@"Jack" forKey:@"name"];
//	对应的崩溃错误信息
//	Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIViewController 0x7fd7b2f4a0d0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key name.'
  • 字典中键或值插入空值 nil
NSString *key1 = nil;
NSString *value1 = nil;
NSDictionary *dic1 = @{key1:@"USA"};
//	对应的崩溃信息
//	Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]'
或者
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
[dic setObject:value1 forKey:@"USA"];
也会发生崩溃,但是通过KVC的方式如
[dic setValue:value1 forKey:@"USA"];
却不会发生崩溃,对于字典的KVC方法可以查看
/* Send -setObject:forKey: to the receiver, unless the value is nil, in which case send -removeObjectForKey:.
*/
- (void)setValue:(nullable ObjectType)value forKey:(NSString *)key;
所以相对健壮
  • NSAttributedString初始化时传入空值nil
NSString *string = nil;
NSAttributedString *AttributedString = [[NSAttributedString alloc] initWithString:string];
//	对应的崩溃信息
//	Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'NSConcreteAttributedString initWithString:: nil value'
  • unrecognized selector
[[UIViewController new] performSelector:@selector(test)];
//	对应的崩溃信息
//	Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController test]: unrecognized selector sent to instance 0x7fe479706a10'
  • UITableView 中没有注册cell重用标识,取空的cell为空
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   //	之前并没有在tableView中注册该重用标识
   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell1" forIndexPath:indexPath];
   cell.textLabel.text = [NSString stringWithFormat:@"第%zd行",indexPath.row];
   return cell;
}
//	对应的崩溃信息
//	*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier cell1 - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

另外更新UITableView数据时,前后的数据不同步也会导致该类型的错误

  • Push到同一个控制器多次
 TableViewController *TC = [TableViewController new];
  [self.navigationController pushViewController:TC animated:YES];
  [self.navigationController pushViewController:TC animated:YES];
  [self.navigationController pushViewController:TC animated:YES];
//	对应的崩溃信息
//	Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Pushing the same view controller instance more than once is not supported (<TableViewController: 0x7f84c551aaa0>)'

那么对于iOS 提供的 try-catch 可以捕获上述哪几种错误呢?

  • unrecognized selector
  • NSAttributedString初始化时传入空值nil
  • 数组越界访问
  • KVC赋值给一个没有定义的key
  • 字典中键或值插入空值 nil
  • NSAttributedString初始化时传入空值nil

可见try-catch来说,其能抓取的错误是有限的,对于内存溢出和野指针问题无能为力;除此之外,try-catch还可能产生以下问题

  • 即使在ARC下,内存释放的代码会因为try-catch的中断不能执行,会造成内存泄漏;对于采用GC来释放内存的java等语言,不会存在此问题
  • exception使用block造成额外的开销,效率较低

基于上述原因,iOS中的try-catch使用并不如Android开发中使用的那么频繁

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值