美文网首页
iOS 内存管理机制

iOS 内存管理机制

作者: 凛冬将至2002 | 来源:发表于2019-04-20 19:14 被阅读0次

    iOS内存管理机制原理

    iOS内存管理机制的原理是引用计数,引用计数是一个简单而有效的管理对象生命周期的方式。当这块内存被创建出来的时候,他的引用计数从0增加到1,表示有一个对象或指针持有这块内存,拥有这块内存的所有权,如果这时有另外的对象或指针指向这块内存,那么为了表示这个后来的对象或指针拥有这块内存的所有权,引用计数加1变为2,之后如果有一个对象或者指针不在指向这块内存,引用计数就减1,表示这个对象或指针不在拥有这块内存的所有权,当一块内存的引用计数变为0,表示没有任何对象或者指针持有这块内存,系统便会立即释放这块内存。

    • 当我们创建一个新对象时,它的引用计数为1。
    • 当有一个新的指针指向这个对象时,我们将引用计数加1。
    • 当某个指针不再指向这个对象时,我们将引用计数减1。
    • 当对象的引用计数为0时,说明这个对象不再被任何指针指向了,就可以将对象销毁,回收内存

    ARC下的内存管理问题

    1.循环引用(Reference Cycle)问题

    引用计数这种管理内存的方式虽然很简单,但是有一个比较大的瑕疵,即它不能很好的解决循环引用问题。如下图所示:对象 A 和对象 B,相互引用了对方作为自己的成员变量,只有当自己销毁时,才会将成员变量的引用计数减 1。因为对象 A 的销毁依赖于对象 B 销毁,而对象 B 的销毁与依赖于对象 A 的销毁,这样就造成了我们称之为循环引用(Reference Cycle)的问题,这两个对象即使在外界已经没有任何指针能够访问到它们了,它们也无法被释放。 不止两对象存在循环引用问题,多个对象依次持有对方,形式一个环状,也可以造成循环引用问题,而且在真实编程环境中,环越大就越难被发现。下图是 4 个对象形成的循环引用问题。

    主动断开循环引用

    解决循环引用问题主要有两个办法,第一个办法是我明确知道这里会存在循环引用,在合理的位置主动断开环中的一个引用,使得对象得以回收。如下图所示:
    1. __weak
      __weak 表示弱引用,对应定义 property 时用到的 weak。弱引用不会影响对象的释放,而当对象被释放时,所有指向它的弱引用都会自定被置为 nil,这样可以防止野指针。使用__weak修饰的变量,即是使用注册到autoreleasePool中的对象。__weak 最常见的一个作用就是用来避免循环循环。需要注意的是,__weak 修饰符只能用于 iOS5 以上的版本,在 iOS4 及更低的版本中使用 __unsafe_unretained 修饰符来代替。

    __weak 的几个使用场景:

    • 在 Delegate 关系中防止循环引用。
    • 在 Block 中防止循环引用。
    • 用来修饰指向由 Interface Builder 创建的控件。比如:@property (weak, nonatomic) IBOutlet UIButton *testButton;。

    _weak弱引用的实现原理
    对于__weak内存管理也借助了类似于引用计数表的散列表,它通过对象的内存地址做为key,而对应的__weak修饰符变量的地址作为value注册到weak表中,在上述代码中objc_initweak就是完成这部分操作,而objc_destroyWeak
    则是销毁该对象对应的value。当指向的对象被销毁时,会通过其内存地址,去weak表中查找对应的__weak修饰符变量,将其从weak表中删除。所以,weak在修饰只是让weak表增加了记录没有引起引用计数表的变化。

    相关文章

      网友评论

          本文标题:iOS 内存管理机制

          本文链接:https://www.haomeiwen.com/subject/cmblgqtx.html