【面试题】用assign修饰object类型会怎样?

问题级别:初级题目

在我们的编码过程中已经养成了使用assign修复基本数据类型的良好习惯,我们不会去使用assign修饰对象类型属性,但是如果用assign去修复对象类型会怎样呢,你可能会有以下猜测:

  • 1.编译会报错;
  • 2.编译不报错,运行正常;
  • 3.编译不报错,运行不正常;
    1. 还是???

开始实验

首先定义一个简单的object类型,重写dealloc方便查看对象的释放

@interface TestObject : NSObject

@property (nonatomic, assign) NSInteger age;

@end


@implementation TestObject

- (void)dealloc {
    NSLog(@"%s", __FUNCTION__);
}

@end

@interface BasicViewController : BaseViewController

@property (nonatomic ,assign) TestObject *property1;

@end
测试一
- (void)test {
    self.property1 = [TestObject new];
    self.property1.age = 1;
}
测试二
- (void)test {
    TestObject *obj = [TestObject new];
    self.property1 = obj;
    self.property1.age = 1;
}

实验结果和分析

测试一

结果:编译后会在self.property1 = [TestObject new];这一行报出警告;运行后断点单步调试后发现TestObject对象会在创建完以后被释放,所以下面一行代码self.property1.age = 1的执行,属性赋值将直接引发crash:EXC_BAD_ACCESS,这就是是所谓的野指针(对一个已经标记为释放的地址读写操作)。

分析:因为TestObject new对象创建出来没有任何强指针指向它,所以创建完以后立即会被释放了,这时候self.property1指针指向的地方已经标记为空闲地址,所以就成了野指针(这个野指针指向的堆空间可能会有2种情况,1.一直空闲没有分配给其他对象;2.分配给其他对象;第一种情况我们代码执行不会有问题,第二种情况很有可能我们访问的属性在这个新对象上面没有,会引发【找不到方法】崩溃)。

测试二

结果:编译正常没有警告,运行正常也没有报错,但是在test方法调用之后如果你再去调用属性property1同样【极可能】会引发EXC_BAD_ACCESS。

分析:因为objtest方法内的临时变量,ARC模式下编译器会在test方法的末尾调用obj release,所以self.property1.age = 1这样代码执行并没有问题,因为该对象此刻仍然被obj的强引用所牵引,然而一旦test方法执行完毕以后,该临时变量就会被释放,此时self.property1将变为野指针。由于这种情况下在编译阶段我们的代码都不会有任何的警告,而运行时该属性变为野指针之后,我们在任何地方调用就会引发野指针崩溃,这是很危险的。

总结

在快速编码的时候,很有可能由于我们的复制粘贴代码而把object类型属性用assign修饰,因为曾经就遇到过同事留下的这种坑,从逻辑上找根本找不错错误,仔细检视代码才发现了这个低级错误。

野指针的行为

使用野指针不一定百分百发生crash,这要看当时内存的使用情况,所以野指针的行为是多变不可预测的。野指针指向的地址空间在对象释放时被标记为空闲地址,接下来再去调用该野指针操作将有下列几种行为:

  1. 该空间一直空闲,调用该属性会引发EXC_BAD_ACCESS;
  2. 该空间被其他对象申请并占用,当调用该野指针的方法methodA时,这个空间上被分配的新对象并没有方法methodA, 会出现方法找不到:[xxx methodA] unrecognized selector sent to instance 0x1xxxxxxxx;
  3. 该空间被其他对象申请并占用,当调用该野指针的方法methodA时,这个空间上被分配的新对象刚好也包含方法methodA, 调用之后不会出现任何crash;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 多线程、特别是NSOperation 和 GCD 的内部原理。运行时机制的原理和运用场景。SDWebImage的原...
    LZM轮回阅读 6,083评论 0 12
  • iOS面试小贴士 ———————————————回答好下面的足够了------------------------...
    不言不爱阅读 6,182评论 0 7
  • 1.写一个NSString类的实现 +(id)initWithCString:(c*****t char *)nu...
    韩七夏阅读 9,166评论 2 37
  • 史上最全的iOS面试题及答案 迷途的羔羊--专为路痴量身打造的品牌。史上最精准的定位。想迷路都难!闪电更新中......
    南虞阅读 5,415评论 0 8
  • 夜雨潇潇欲断魂 风声恰似睢鸠鸣 孔雀东南难离分 雨水涔涔泪涔涔 相思泪洒相思枕 钟声悠悠烛影摇 望穿风雨夜归人 (...
    风起龙飞阅读 2,985评论 1 9