面试题:runtime如何实现weak属性?(转)

weak此特质表明该属性定义了一种「非拥有关系」(nonowning relationship)。为这种属性设置新值时,设置方法既不持有新值(新指向的对象),也不释放旧值(原来指向的对象)。

runtime 对注册的类, 会进行布局,对于 weak 对象会放入一个 hash 表中。 用 weak 指向的对象内存地址作为 keyValueweak 指针 的地址(这个地址的值是所指对象指针的地址)数组,当此对象的引用计数为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,最后把这个 entryweak表中删除,最后清理对象的记录。