__weak简析

当一个 __weak 类型的指针指向的对象被释放时,该指针会自动被置成nil,因此__weak关键字修饰的指针又被称为智能指针。那么这个功能是如何实现的呢?

id __weak obj1 = obj; 

会转化为

id obj1;  
objc_initWeak(&obj1, obj);  
objc_destoryWeak(&obj1);  

即编译器会通过objc_initWeak函数初始化__weak修饰的变量,当变量的作用域结束后会通过objc_destoryWeak函数释放该变量。objc_initWeak函数实际干的活是:

objc1 = 0;  
objc_storeWeak(&obj1, obj);  

这里是先将指针objc1置成0,再调用objc_storeWeak函数使得obj1指向obj对象。
接下来的objc_destoryWeak函数的实际操作如下:

objc_storeWeak(&obj1, 0); 

也就是说,让obj1指针指向的内容变成空。

__weak实现原理

实际上,objc_storeWeak函数会把第二个参数的对象的地址作为key,并将第一个参数(__weak关键字修饰的指针的地址)作为值,注册到weak表中。如果第二个参数为0(说明对应的对象被释放了),则将weak表中将整个key-value键值对删除,这就是__weak关键字的核心思想!

weak表和引用计数表类似,都是通过hash表实现的。如果使用weak表,将被释放的对象地址作为key去检索,就能很高效的获取对应的指向该对象的类型为__weak的指针变量的地址。同时很容易理解,一个对象可能有多个__weak指针指向,因此一个对象地址key可能对应多个值。

在调用对象的release方法时,会在其中一步调用objc_clear_deallocating函数,该函数会执行以下操作:以当前对象的地址作为key,从weak表中获取对应的值----指向该对象的__weak类型的指针变量;将取到的所有指针变量的值赋值为nil;从weak表中删除该key对应的整条记录。

如果大量使用附有__weak修饰符的变量会消耗响应的CPU资源,因此,应该尽量少使用__weak修饰符。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,876评论 8 265
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 13,824评论 1 32
  • 在拉萨 文/闫殿才 《一》 在拉萨,你可以像鹰一样地看 世界很清澈。蓝天,白云,经幡 拉萨河蜿蜒。像膜拜者 转山,...
    闫殿才阅读 3,783评论 30 59
  • 导语:随着大数据的发展,现在出现的列式存储和列式数据库,如Hbase。它与传统的行式数据库有很大区别的。 定义 行...
    jackLee阅读 15,361评论 1 9
  • 我爱你时,你是一切;我不爱你,翻了那页。越是在错误的过去中纠缠,就离前方的幸福越远。 -01- 芋头终于忍无可忍,...
    小马不怕过河阅读 5,464评论 6 19