面试题总结
2019-07-10 本文已影响22人
Figo_OU
- 变量age被定义为NSInteger,它编译时没有问题……但为什么会crash?
NSInteger age;
UILabel *mylabel=[UILabel new];
mylabel.text=age?[NSString stringWithFormat:@"%@",age]:@"";
NSInteger的默认值:
https://blog.csdn.net/yasi_xi/article/details/46784685
可以猜测,age所在的是常量存储区(.text区)。在常量存储区系统不保证初始化的数据为0.
那么我们知道了age肯定不为0了,因为如果为0 ,程序就不会crash了。
那么肯定就会执行到[NSString stringWithFormat:@"%@",age]中。而格式化字符串的时候其实就是调用的下面三个方法。
-initWithFormat:locale:
-initWithFormat:locale:arguments:
+localizedStringWithFormat:
这里就涉及到字符串本地化的问题了。因为%@,所以取出的对象将会调用descriptionWithLocale或者description方法。
“如果对象响应 -descriptionWithLocale: 方法,则调用它,否则调用 -description”
这里参考了ObjC中国的「玩转字符串 」文章https://objccn.io/issue-9-2/
那么重点来了,由于是%@,那么就会根据地址值去找这个对象。如果age是对象,那么假设age指针的值是0x10a2f1768。那么就会对0x10a2f1768所指向的对象发送description消息。所以如果是对象那么这里没有任何问题。
然而age是一个数字,那么这里会将这个数字转化为16进制的值,假设age的值为18。那么这里将向0x12这个地址所指向的对象发送description消息。因为这个0x12是指向不可用内存的指针,那么就会发生野指针错误。
野指针错误
野指针例子
NSObject *stu = [[NSObject alloc] init];
// [stu setAge:10]; 这报的是方法找不到
[stu release];
[stu setAge:10];//这报的是野指针错误。