weak
此特质表明该属性定义了一种「非拥有关系」(nonowning relationship)。为这种属性设置新值时,设置方法既不持有新值(新指向的对象),也不释放旧值(原来指向的对象)。
runtime
对注册的类, 会进行布局,对于weak
对象会放入一个hash
表中。 用weak
指向的对象内存地址作为key
,Value
是weak
指针 的地址(这个地址的值是所指对象指针的地址)数组,当此对象的引用计数为0
的时候会dealloc
,假如weak
指向的对象内存地址是a
,那么就会以a
为键, 在这个 weak 表中搜索,找到所有以a
为键的weak
对象,从而设置为nil
。
runtime
如何实现weak
属性具体流程大致分为 3 步:
- 1、初始化时:
runtime
会调用objc_initWeak
函数,初始化一个新的weak
指针指向对象的地址。- 2、添加引用时:
objc_initWeak
函数会调用objc_storeWeak()
函数,objc_storeWeak()
的作用是更新指针指向(指针可能原来指向着其他对象,这时候需要将该weak
指针与旧对象解除绑定,会调用到weak_unregister_no_lock)
,如果指针指向的新对象非空,则创建对应的弱引用表,将weak
指针与新对象进行绑定,会调用到weak_register_no_lock
。在这个过程中,为了防止多线程中竞争冲突,会有一些锁的操作。- 3、释放时:调用
clearDeallocating
函数,clearDeallocating
函数首先根据对象地址获取所有 weak 指针地址的数组,然后遍历这个数组把其中的数据设为nil
,最后把这个entry
从weak
表中删除,最后清理对象的记录。
网友评论