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的原理的主要内容,如果未能解决你的问题,请参考以下文章

[OC学习笔记]weak的实现原理

iOS weak底层实现原理

oc中 关于weak的粗浅理解

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

iOS 面试题:weak 的内部实现原理 --转自唐巧

Objective-C中,ARC下的 strong和weak指针原理解释