问题:Runtime如何实现weak变量的自动置nil?

  • weak属性的特点:

weak 表明该属性定义了一种“非拥有关系” (nonowning relationship)。
weak属性设置新值时,设置方法既不保留新值,也不释放旧值。
assign类似,然而在属性所指的对象释放时候,属性值也会清空(nil out)。

  • runtime是如何实现 weak 变量的自动置nil?

Runtime 对注册的类,会进行内存布局,从一个粗粒度的概念上来讲,这时候weak 对象会放入一个 hash 表中,这是一个全局表,表中是用 weak 指向的对象内存地址作为key,用所有指向该对象的 weak 指针表作为value。当此对象的引用计数为 0 的时候会 dealloc,假如该对象内存地址是 address,那么就会以 addresskey,在这个weak 表中搜索,找到所有以 address 为键的weak对象,从而设置为nil

  • runtime 如何实现 weak 属性具体流程大致分为 3 步:

  1. 初始化时:runtime 会调用 objc_initWeak 函数,初始化一个新的 weak 指针指向对象的地址。
  2. 添加引用时:objc_initWeak 函数会调用objc_storeWeak(&weakPo, Model)函数。

objc_storeWeak(&weakPo, Model)的作用是更新指针指向(指针可能原来指向着其他对象,这时候需要将该 weak 指针与旧对象解除绑定,会调用到 weak_unregister_no_lock),如果指针指向的新对象非空,则创建对应的弱引用表,将 weak 指针与新对象进行绑定(即把赋值对象(Model)的内存地址作为键值key,将weak修饰的属性变量(weakPo)的内存地址(& weakPo)作为value),会调用到weak_register_no_lock,注册到 weak 表中。在这个过程中,为了防止多线程中竞争冲突,会有一些锁的操作。
如果Model为0(nil),那么把变量weakPo的内存地址&weakPoweak表中删除,可以把objc_storeWeak(&weakPo, Model)理解为:objc_storeWeak(value, key),并且当keynil,将valuenil
Modelnil时,weakPoModel指向同一个内存地址,在Modelnil时,weakPonil。此时向weakPo发送消息不会崩溃:在Objective-C中向nil发送消息是安全的

  1. 释放时:调用 clearDeallocating 函数,clearDeallocating 函数首先根据对象地址获取所有 weak 指针地址的数组,然后遍历这个数组把其中的数据设为 nil,最后把这个 entry 从 weak 表中删除,最后清理对象的记录。

你可能感兴趣的:(问题:Runtime如何实现weak变量的自动置nil?)