weak原理探索

weak 指针

weak是弱引用,所引用对象的计数器不会加一,并在引用对象被释放的时候自动被设置为nil。通常用于解决循环引用问题。

weak 表

runtime 维护了一个 weak 表,用于存储指向某个对象的所有 weak 指针。weak 表是一个 hash 表:
weak 表

weak 实现原理

1、初始化时:runtime 会调用 objc_initWeak() 函数,objc_initWeak() 函数会初始化一个新的 weak 指针指向对象的地址。
1
2
// object 是要初始化的指针,value 是指针指向的对象
id objc_initWeak(id *object, id value);

objc_initWeak() 方法的实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
id objc_initWeak(id *location, id newObj) {
// 查看对象实例是否有效
// 无效对象直接导致指针释放
if (!newObj) {
*location = nil;
return nil;
}
// 这里传递了三个 bool 数值
// 使用 template 进行常量参数传递是为了优化性能
return storeWeakfalse/*old*/, true/*new*/, true/*crash*/>
(location, (objc_object*)newObj);
}

这里判断了其指针指向的对象是否有效,无效则直接释放,不再往调用深层函数。若有效,则调用 objc_storeWeak() 函数,要被初始化的指针(object)将被注册为一个指向对象(value)的 __weak 指针对象。

objc_initWeak() 函数有一个前提条件:就是 object 必须是一个没有被注册为__weak 对象的有效指针。而 value 则可以是 null,或者指向一个有效的对象。

2、添加引用时:objc_initWeak() 函数会调用 objc_storeWeak() 函数, objc_storeWeak() 的作用是更新指针指向,创建对应的弱引用表。
1
id objc_storeWeak(id *location, id value);

1)创建 weak 弱引用表
2)解除旧对象的弱引用表
3)将新的弱引用表与对象进行关联绑定

初始化弱引用对象流程

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

Powered by Hexo and Hexo-theme-hiker

Copyright © 2013 - 2019 Acan's blog All Rights Reserved.

访客数 : | 访问量 :