oc中 关于weak的粗浅理解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oc中 关于weak的粗浅理解相关的知识,希望对你有一定的参考价值。

参考技术A

这两天在研究oc中的weak实现原理,只是看明白了一点浅显的东西,参考地址:
https://www.jianshu.com/p/2c2da28a5a53

以下是自己的理解:

基本用法:

如果是面试,面试官肯定会要深入的问,为什么对象释放的时候,指针会自动置为 nil ,如何实现的?

系统维护了一个全局的map表。这个表里有多个 sideTable ,sideTable里面有 weak_table (弱引用表)

当通过 __weak 让一个指针指向一个对象的时候,如果这个对象之前没有被注册,就会调用 objc_initWeak() 方法
如果是已经注册的,会调用 objc_storeWeak() 。对象销毁的时候,会调用 objc_destroyWeak()
当然, objc_initWeak() 和 objc_destroyWeak() 最终都会调用 objc_storeWeak() 。

objc_storeWeak() 这个方法里,先根据对象的地址,从全局map表中找到对应的 sideTable ,然后再从 sideTable 中找到对应的 weak_table ,找到弱引用表后,生成或者更新 weak_entry_t 。 weak_entry_t 里面存了对象的地址和指向对象的所有弱引用指针。

对象销毁的时候,是找到对应的 weak_entry_t ,把里面的指针都移除掉

OC中weak的原理

参考技术A

  weak是OC中用于打破对象间的循环引用的一种技术。
1. weak 修饰一个变量时,表示该指针变量可以使用但不拥有该对象;及 weak 引用指向对象时,对象的引用计数并不增加。

  当 weak 引用一个对象时,Runtime会将引用的信息( key 为指向对象的指针, value 是 weak 指针的变量的地址数组)封装到 weak_entry_t 结构体中,具体存储到 DisguisedPtr 类中。
  OC的Runtime会维护一个 weak 表( weak_table_t 结构体),用于维护指向对象的所有 weak 指针,是 weak_entry_t 的结构体上的一层封装。
   weak_table_t 类型的结构体,是一个哈希表,但是在这个表中的操作并不是线程安全的。
  于是Runtime对于 weak_table_t 上又进行了一层封装,也就是 SideTable 。 SideTable 这层封装对于 weak 引用机制的主要目的是解决线程安全的问题。

   weak_entry_t 是 weak_table_t 具体存储的数据类型

DisguisedPtr<T> 是Runtime对于普通对象指针(引用)的一个封装,目的在于隐藏 weak_table_t 的内部指针。

   RefcountMap 用于OC的引用计数机制; slock 实际上是 os_unfair_lock_s 类型,用于处理线程安全的问题; weak_table 弱引用表,用于存储对象的弱引用的数组。 SideTable 提供的方法都与锁有关。

strong :该对象强引用delegate,引用计数+1,外界不能销毁 delegate 对象,会导致循环引用( Retain Cycles )

weak :指明该对象并不持有delegate这个对象,delegate的销毁由外部控制。当 delegate 指向的对象销毁后,自动 delegate = nil 。

assign :具有 weak 的效果,但需要手动设置 nil 。

为什么用 weak 不用 assign ?
assign 是指针赋值,不操作引用计数, delegate 用完后如果没有设置为 nil ,有可能产生野指针;而 weak 指向的 delegate 一旦用完,自动就 nil 了,不会产生野指针。

assign :一般修饰值类型的属性;
strong :修饰引用类型的属性,内存计数+1;
weak :修饰引用类型的属性,原理见上述讲解;但是 weak 修饰的属性虽然不持有,在释放对象时会查询和释放其对应的弱引用表,这样是会增加内存和性能上的开销。

OC Runtime之Weak(3)
OC Runtime之Weak(2)
OC Runtime之Weak(1)

以上是关于oc中 关于weak的粗浅理解的主要内容,如果未能解决你的问题,请参考以下文章

关于OC中的block自己的一些理解

OC中weak的原理

关于jsp页面用js获取session的粗浅笔记

关于逻辑回归和感知器一些基础知识的理解

iOS之weak和strong懒加载及循环引用

OC对象之旅 weak弱引用实现分析