您的位置:首页 > 移动开发 > IOS开发

iOS runtime探究(五): 从runtime开始深入weak实现机理

2017-03-28 17:20 405 查看

你要知道的runtime都在这里

转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639341

本文主要讲解
runtime
相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向:

从runtime开始: 理解面向对象的类到面向过程的结构体

从runtime开始: 深入理解OC消息转发机制

从runtime开始: 理解OC的属性property

从runtime开始: 实践Category添加属性与黑魔法method swizzling

从runtime开始: 深入weak实现机理

本文是系列文章的第五篇文章,也是系列文章的最后一篇从runtime开始: 深入weak实现机理,本文主要讲解
runtime
是如何实现
weak
修饰符的。

weak
修饰符我们一点也不陌生在开发中经常用到,最主要的作用是为了防止
引用循环(retained cycle)
,经常用于
block
delegate
,在前面几篇文章中已经讲解了
weak
的基本使用和引用循环,如果有兴趣可以参考文章iOS @property探究(一): 基础详解iOS @property探究(二): 深入理解iOS block探究(一): 基础详解iOS block探究(二): 深入理解,相关方法和特点本文不再赘述了。

weak

weak
不论是用作
property
修饰符还是用来修饰一个变量的声明其作用是一样的,就是不增加新对象的引用计数,被释放时也不会减少新对象的引用计数,同时在新对象被销毁时,
weak
修饰的属性或变量均会被设置为
nil
,这样可以防止野指针错误,本文要讲解的也正是这个特性,
runtime
如何将
weak
修饰的变量的对象在销毁时自动置为
nil


那么
runtime
是如何实现在
weak
修饰的变量的对象在被销毁时自动置为
nil
的呢?一个普遍的解释是:
runtime
对注册的类会进行布局,对于
weak
修饰的对象会放入一个
hash表
中。用
weak
指向的对象内存地址作为
key
,当此对象的引用计数为0的时候会
dealloc
,假如
weak
指向的对象内存地址是
a
,那么就会以
a
为键在这个
weak表
中搜索,找到所有以
a
为键的
weak
对象,从而设置为
nil


了解了以上知识后就可以深入
runtiem
代码来看看具体实现细节,有兴趣的读者可以继续阅读。

深入runtime理解weak

这部分内容参考《Objective-C高级编程:iOS与OS X多线程和内存管理》,可以看出具体的实现方式就是使用了一个
HashTable


NSString *name = [[NSString alloc] initWithString: @"Jiaming Chen"];
__weak NSString *weakStr = name;


当为
weakStr
这一
weak
类型的对象赋值时,编译器会根据
name
的地址为key去查找
weak哈希表
,该表项的值为一个数组,将
weakStr
对象的地址加入到数组中,当
name
变量超出变量作用域或引用计数为0时,会执行
dealloc
函数,在执行该函数时,编译器会以
name
变量的地址去查找
weak哈希表
的值,并将数组里所有
weak
对象全部赋值为nil。

备注

由于作者水平有限,难免出现纰漏,如有问题还请不吝赐教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios 面向对象 class