数组越界
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也会崩溃