重新认识ARC

3 篇文章 0 订阅
1 篇文章 0 订阅

虽然用了很久的ARC,感受了代码简洁。但是对ARC底层实现并不了解。

今天抽空研究了下,做些简单地总结。

一、__strong

1.局部变量

①.对于局部变量来说,在超出作用域的地方由编译器自动插入release。

{

id__strong objc = [NSObject new];

}

==>>  (大概转化为)

{

id objc =objc_msgSend(objc_getClass("NSObject"),@selector(new));

objc_release(objc);

}

②.在非ARC返回的autorelease类型的方法

{

id__strong objc = [NSMutableArray array];

}

==> (在Blog手码大概代码,如有错误还望指出)

{

id objc =objc_msgSend(NSMutableArray,@selector(array));

objc_retainAutoreleaseReturnValue(objc);

objc_release(objc);

}

这里比①多了一步 objc_retainAutoreleaseReturnValue(objc);对autorelease类型做了一个不retain。

我们来猜测 [NSMutableArray array] 内部的实现

+(id)array

{

return{ [NSMutableArray alloc] init];

}

==> 转化后

{

id tmp =objc_msgSend(NSMutableArray,@selector(alloc)));

  objc_msgSend(tmp,@selector(init));

return objc_autoreleaseReturnValue(tmp);

}

这里边对tmp做了objc_autoreleaseReturnValue操作,这个操作跟objc_autorelease()是有区别的。objc_autoreleaseReturnValue会检查命令栈(具体叫什么名字有点迷糊了)如果发现紧接其后调用了objc_retainAutoreleaseReturnValue方法,就不会将tmp加入到autoreleasepool中。而objc_autorelease会直接把对象放入到pool中。

所以:类方法返回的对象如果被__strong修饰,其实并没有加入到pool中,算是编译器优化~

2.实例变量

我以前一直以为是在dealloc中被ARC插入release的。后来发现是编译器利用了C++的一个特性。C++生成了个xxxDestu..(这个     文件名记不清 楚了,稍后补上),编译器会在这里处理实例变量的释放。当然按照之前的理解也没什么大碍~~


二、__weak

被__weak修饰的变量,被加入到weak表中,以它所指向的对象的地址作为key。在对象被释放时,会将weak表中的所有注册weak变量移除并置为nil。

①.被声明时

{

id__weak wkOBJC = objc;

}

==>>

{

id wkOBJC =nil;

objc_initWeak(&wkOBJC,objc);

objc_destoryWeak(&wkOBJC);

}

其中objc_initWeakobjc_destoryWeak内部都是使用的objc_storeWeak();

objc_initWeak

 ==>>  

{

id tmp = 0;

return objc_storeWeak(&tmp,objc)

}

对应的objc_destoryWeak

==>>

{

objc_storeWeak(&wkOBJC,0)

}

__weak在被声明时,通过objc_storeWeak加入到注册表中。

②.在被使用时

{

id __weak wkOBJC = objc;

NSLog(@"%@",wkOBJC);

}

==>>

{

id wkOBJC = nil;

objc_initWeak(&wkOBJC,objc);

objc_destoryWeak(wkOBJC);

id tmp =objc_loadWeakRetained(&wkOBJC);

objc_autorelease(tmp);

NSLog(@"%@",tmp);

objc_destroyWeak(&wkOBJC)

}

可以看到在使用__weak修饰的变量时,会使用一个中间变量retain一次,然后再加入到autoreleasepool。如果多次使用,就会生成大量的autorelease对象到pool中。作为优化,可使用 id __strong sOBJC = wkOBJC.



后记:有纰漏再补充~


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值