OC中weak的原理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的原理的主要内容,如果未能解决你的问题,请参考以下文章