下面着重探讨2个问题的内部实现原理
1.若附有__weak修饰符的变量所引起的对象被废弃,则将nil赋值给该变量
2.使用__weak修饰的变量,即是使用注册到autoleasepool中的对象
<pre>id __weak obj1 = obj; //假设变量obj附加__strong修饰符且对象被赋值
</pre>
<pre>id obj1; objc_initweak(&obj1,obj); objc_destroyWeek (&obj1);
</pre>
通过objc_initWeak函数初始化附有__waek修饰符的变量,在变量作用域结束时通过objc_destoryWeak函数释放该变量.
如下源码所示,objc_initWeak函数讲附有__waek修饰符的变量初始化为0后,会将赋值的对象作为参数滴啊用objc_storeWeak函数.
<pre>obj1= 0; objc_storeWeak (&obj1, obj); //objc_destroyWeek函数将0作为参数调用objc_storeWeak函数. objc_storeWeak(&obj1, 0);
</pre>
objc_storeWeak函数把第二参数的赋值对象的地址未做键值,将第一参数的附有__weak修饰符的变量的地址注册到weak表中.如果第二参数为0,则把变量的地址从weak表中删除.
weak表
weak表与引用计数表相同,作为[散列表](a href = "http://www.cnblogs.com/dolphin0520/archive/2012/09/28/2700000.html")被实现.如果使用weak表,将废弃对象的地址作为键值进行检索,就能搞死的获取对象的附有__weak修饰符的变量地址,另由于一个对象可同时赋值给多个附有__weak修饰符的变量中,所以对于一个键值,可以注册多个变量的地址.
释放对象时,废弃谁都不持有的对象的同时,程序的动作是怎样的呢? 下面我们来跟踪观察.对象将通过objc_release函数释放.
(1)objc_release
(2)因为引用计数为0所以执行delloc
(3)_objc_rootDealloc
(4)objc_dispose
(5)objc_destructInstance
(6)objc_clear_deallocating
对象被废弃时最后调用的objc_clear_deallocating函数的动作如下:
1.从weak表中获取废弃对象的地址为键值的记录.
2.将包含在记录中的所有附有__weak修饰符变量的地址,赋值为nil.
3.从weak表中删除该记录.
4.从引用计数标中删除废弃对象的地址为键值的记录
根据上述步骤,前面说的吐过有__weak修饰符的变量引用的对象被废弃,则将nil赋值给该变量这一操作,则会消耗相应的CPU资源.最好是只在需要避免循环引用时用__weak修饰符.