深入探讨 iOS weak 底层原理
2023-11-25 17:21:55
一抹暖意——深入探讨iOS weak底层原理
我们一直都很熟悉Objective-C,对strong,retain,release也很熟悉,
在swift出来之后,weak,unsafe_unretained这些新东西,尤其unsafe_unretained的概念也比较难以理解。
但是,如果我们真的想要搞懂内存管理,就必须搞明白weak,unsafe_unretained到底是什么。
关于unsafe_unretained我们后续说,现在我们首先讨论一下weak,我们利用类比的方式,回顾下release和retain。
retain的概念如同向银行存钱,release就是从银行取钱。
weak是什么?
weak是另外一种关系,我们简单看下它的定义,weak的英文是虚弱、脆弱的,这里我们也可以理解为指向内存地址的引用发生关系。
weak和strong的区别
- weak可以为nil,而strong肯定是有值的。
- weak对象指向的内存如果释放了,weak的指针会自动变成nil,而strong会引发crash。
我们继续看下weak的底层原理。
weak底层原理
strong会引用到对象头中的isa指针,而weak不会,weak指针的结构和strong指针完全不一样,引用的是ISA指针之后的指针,如下图:
struct WK {
void * isa;
void * newIsa;
};
weak指针是只读的,结构体只有get没有set方法。
weak的引用计数
前面我们说weak会把指针指向isa之后的指针,同时weak还维护了一个引用计数,这个引用计数不是指向对象本来的引用计数,而是用来记录有多少个weak指向的对象。
当weak指向的对象被释放时,weak会自动将对象地址置为nil,同时将引用计数置为0,而weak引用对象的isa指针仍然指向当前对象,不会改变。
weak对内存管理至关重要,内存管理的核心就是管理指针,减少野指针的产生。
weak的用法
weak主要用于修饰实例变量,当weak修饰的实例变量所指向的对象被释放后,weak指向的对象会被自动设置为nil。这可以防止野指针的产生,避免程序崩溃。
弱引用的优点
- 可以避免野指针的产生。
- 可以提高程序的健壮性。
- 可以减少内存泄漏的风险。
弱引用的缺点
- 只能用于实例变量。
- 不能用于修饰全局变量。
- 不能用于修饰静态变量。
- 不能用于修饰局部变量。
weak的注意事项
- weak指针不能用作参数传递。
- weak指针不能用作方法的返回值。
- weak指针不能用作属性的类型。
- weak指针不能用作协议的类型。
weak应用场景
- 避免野指针的产生。
- 防止程序崩溃。
- 减少内存泄漏的风险。
- 实现循环引用。
结语
weak是iOS开发中非常重要的一个概念,理解了weak的原理和用法,可以帮助我们更好地进行内存管理,避免野指针的产生,提高程序的健壮性。