14、Swift的自动引用计数

ARC

  • Swift使用自动引用计数(ARC)来跟踪并管理应用使用的内容。当实例不被使用时,ARC会自动释放这些类的实例所占用的内存。
  • 引用计数只应用在类的实例。结构体和枚举类型都是值类型,并非引用类型,不是以引用类型的方式来存储和传递的。

ARC是如何工作的

  • 每次创建一个类的实例,ARC都会分配一个内存块,用来存储这个实例的相关信息。这个内存块保存着实例的类型,以及这个实例相关的属性的值。
  • 当实例不在被使用时,ARC会释放这个实例使用的内存空间。
  • 但是如果ARC释放了仍在使用的实例,那么你就不能再访问这个实例的属性和方法。如果你仍然在试图访问这个实例,有可能会崩溃
  • 为了保证不会发生上述情况,ARC跟踪与类的实例相关的属性、常量以及变量的数量。只要有一个有效的引用,ARC都不会释放这个实例。
  • 只要你将一个类的实例赋值给一个属性或者常量或者变量,这个属性、常量或者变量就是这个实例的强引用。之所以称为强引用,是因为它强持有这个实例,并且只要这个强引用还在,实例就不能被销毁。

循环引用

  • 在两个类实例彼此保持对方的强引用,使得每个实例都使对方保持有效时会发生这种情况。
  • 通过弱引用或者无主引用来取代强引用,可以解决强引用引起的循环引用。
    在这里插入图片描述
class Person {
    let name:String
    init(name:String){
        self.name = name
    }
    var department:Apartment?
    deinit {
        print("\(name) is being deinitialized")
    }
}

class Apartment {
    let unit:String
    init(unit:String){
        self.unit = unit
    }
    var tenant:Person?
    deinit {
        print("Apartment \(unit) is being deinitialized")
    }
}

解决循环引用

  • 弱引用和无主引用允许引用环中的一个实例引用另外一个实例,但是不是强引用。因此实例可以相互引用但是不会产生强引用环。
  • 对于生命周期中引用会变为nil的实例,使用弱引用;对于初始化时赋值之后再也不会赋值为nil的实例,使用无主引用。

弱引用

  • 弱引用不会增加实例的引用计数,因此不会阻止ARC销毁被引用的实例。这种特性使得引用不会变成强引用环。声明属性或者变量的时候,关键字weak表明引用为弱引用。
  • 弱引用只能声明变量类型,因为运行时它的值是可以改变的。弱引用绝对不能声明为常量。
  • 因为弱引用可以没有值,所以声明弱引用的时候必须是可选的。在Swift语言中,推荐使用可选类型来作为可能没有值的引用的类型。
 weak var tenant:Person?

无主引用

  • 无主引用默认始终有值。因此,无主引用只能定义为非可选类型。在属性。变量前添加unowned关键字,可以声明一个无主引用。
  • 因为是非可选类型,因此当使用无主引用的时候,不需要展开,可以直接访问。不过非可选类型变量不能赋值为nil,因此当实例对象销毁的时候,ARC无法将引用赋值为nil。
  • 当实例被销毁后,试图访问该实例的无主引用会触发运行时错误。使用无主引用时请确保引用始终指向故意未销毁的实例。
 unowned var countty:Country

闭包引起的循环引用

将一个闭包赋值给类实例的某个属性,并且这个闭包使用了实例,这样也产生了强引用环。这个闭包可能访问了实例的某个属性,或者调用了实例的某个方法。这两种情况都导致了闭包使用self,从而产生循环引用。

闭包引用循环解决

定义占有列表-占有列表中的每个元素都是由weak或者unowned关键和实例的引用(如self或者someInstance)组成。每一对都在中括号,通过逗号隔开。
当闭包和占有的实例总是相互引用并且总是同时销毁时,将闭包内的占有定义为无主引用。
相反的,当占有引用可能会是nil,将闭包内的占有引用定义为弱引用。

   lazy var someClosure = {
        [unowned self,weak delegate = self.delegate] (index:Int,stringToProcess:String) in
        //
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值