iOS常见的崩溃

2019-01-14  本文已影响8人  阿龍飛

数组越界

NSArray *firstNames = @[@"Roy", @"Mike", @"Jordan"];
NSString *name = firstNames[3]; // 崩溃

崩溃信息:
**** 
Terminating app due to uncaught exception 'NSRangeException', 
reason:
 '*** -[__NSArrayI objectAtIndexedSubscript:]: index 3 beyond bounds [0 .. 2]' 
*****

分析:
可以看出当前数组的范围是0..2,当前下标超出了范围,即访问了未知的内存空间

注:
除了数组可能越界之外,字符串也有可能越界,
例如执行substringWithRange:消息时如果传递了过大的范围也会崩溃

字面量数组和字典插入nil值

NSString *name;
NSArray *firstNames = @[@"Roy", @"Mike", @"Jordan", name];  //崩溃

崩溃信息:
****
Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason:
'*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[3]'
******

分析:
通过崩溃信息可以很清楚看到是因为在字典初始化的时候插入了nil,实际上字面量语法是一种语法糖,
本质是先创建了一个数组,然后把方括号内的所有对象添加到这个数组中

注:
字面量语法让代码更加简洁,也能及时发现错误,但是最后创建的数组是不可变的

字典

NSNumber *jordanAge;
NSDictionary *ages = @{@"Roy":@22, @"Mike":@24, @"Jordan":jordanAge};       //崩溃

崩溃信息:
**** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 
'*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[2]'*
*****

分析:
同上面原因一样,都是插入了nil而导致的崩溃

注:
当key为nil的时候插入也会崩溃

Unrecognized Selector

id person = @"person";
[person objectForKey:@"name"];  //崩溃

崩溃信息:
**** 
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 
'-[__NSCFConstantString objectForKey:]: unrecognized selector sent to instance 0x1000010e8'*
*****

分析:
person对象无法执行objectForKey:消息,所以最后崩溃了

注:
在用Objective-C语言编码时,我们会常常使用id类型更加便利地声明变量,但在执行消息前一定要确定它是否能响应,
可使用respondsToSelector:检查。最常见的场景是调用代理方法,即使指定了代理对象,
也不一定保证代理实现了相应方法(协议里还有可选实现的方法)

NaN崩溃

float number = NAN;
NSDictionary *dict = @{@"value" : @(number)};
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingSortedKeys error:nil];

崩溃信息:
****
Terminating app due to uncaught exception 'NSInvalidArgumentException',
 reason: 'Invalid number value (NaN) in JSON write'*
*****

分析:
可以先来判断dict对象是否能被转换成JSON数据:
BOOL isValidJSONObject = [NSJSONSerialization isValidJSONObject:dict];
isValidJSONObject的结果是NO,也就是dict对象无法被转换为JSON数据,即NaN类型不能被用于JSON对象中

注:
当进行不正常的数学运算时不只是会产生NaN类型,也有可能产生+inf类型,虽然并不会直接造成崩溃,
但有可能在用它们进行其他操作的时候会有可能造成崩溃。通过isnan(x)和isinf(x)方法可以判断nan和inf类型

富文本初始化时字符串为空

NSString *text;
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text]; // 崩溃

崩溃信息:
**** 
Terminating app due to uncaught exception 'NSInvalidArgumentException',
 reason: 'NSConcreteAttributedString initWithString:: nil value'*
*****

分析:
从崩溃信息中可以很明显看到是因为传入的变量值为nil而崩溃

注:
构造NSMutableString时,如果传入的字符串为nil也会崩溃
上一篇 下一篇

猜你喜欢

热点阅读