swift-ARC

作者: dio__ | 来源:发表于2016-12-30 19:04 被阅读0次

自动引用计数(ARC)主要用来跟踪和管理应用程序的内存,通常不需要手动维护,我这里只是记录三个官方例子的使用场景


循环强引用

使用场景:当一个人和一个房间互相绑定的时候,假设需要注销某一对象的时候,因为资源还在互相占用,会出现无法注销的情况

引起问题: 编译型语言与脚本语言不同,执行完后不会直接注销,即使手动注销实例,即使手动注销实例也不会生效,造成内存泄露

class Person{
    let name: String
    var apartment: Apartment?
    
    init(name: String){
        self.name = name
    }
    
    deinit{
        print("\(self.name) is begin deinitialized")
    }
}

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

以上代码中, 假设将4A房间绑定给john,同时将john绑定给这个4A房间

var john: Person?
    john = Person(name: "john")
var unit4A: Apartment?
    unit4A = Apartment(unit: "4A")
john?.apartment = unit4A
unit4A?.tenant = john

这时候 房子的实例和人的实例是互相绑定的, 如果某天 john因为写代码加班猝死了,这时候注销john4A房间的时候就会出现无法解绑的情况,执行:

john = nil
unit4A = nil

并没有调用 Person的 deinit,也没有调用Apartment的 deinit, 这就是互相强引用的问题

弱引用

使用场景: 出现以上情况怎么办,那就使用弱引用, 在房主对象前使用 weak 关键字,如下代码

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

使用相同的调用方式

var john: Person?
john = Person(name: "john")
var unit4A: Apartment?
unit4A = Apartment(unit: "4A")
john?.apartment = unit4A
unit4A?.tenant = john

剧情还是一样,john 因为某些原因挂掉了,所以要注销掉john:
john = nil
这时候可以发现触发了Persondeinit:
ohn is begin deinitialized
如果jhon 还活着,直接想改他的房产证:
unit4A = nil
结果很圆满,没有执行任何 deinit

无主引用

使用场景:一个人可能不会拥有信用卡, 但是每个信用卡一定会有一个主人,无主引用与被引用对象持有相同的生命周期,需要在声明前加unowned关键字

class Customer{
    let name: String
    var card: CreditCard?
    
    init(name: String){
        self.name = name
    }
    
    deinit {
        print("\(name) is begin deinitialized")
    }
}

class CreditCard{
    let number: UInt64
    unowned let customer: Customer
    
    init(number: UInt64, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    
    deinit {
        print("Card #\(self.number) is begin deinitialized")
    }
}

以上代码描述 一个信用卡与一个持卡人关系,这里实例了一个 jane 和一张信用卡

var jane: Customer?
jane = Customer(name: "jane")
jane?.card = CreditCard(number: 1234_5678_9012_3456, customer: jane!)

信用卡与jane是绑定关系, 假设jane也因为加班猝死了,那这张卡也随之会被注销掉

jane = nil
//把jane 注销后, 触发了 jane的 deinit 和 card 的 deinit

jane is begin deinitialized
Card #1234567890123456 is begin deinitialized

相关文章

  • swift-ARC

    自动引用计数(ARC)主要用来跟踪和管理应用程序的内存,通常不需要手动维护,我这里只是记录三个官方例子的使用场景 ...

  • Swift-ARC(Automatic Reference Co

    Swift管理内存方式和OC极其相似,都是采用自动引用计数 ARC机制来跟踪和管理。ACR 会在实例不再使用的情况...

  • Swift-ARC(Automatic Reference Co

    了解java的童鞋都知道GC(垃圾回收),程序员不需要去关心内存动态分配和垃圾回收的问题,交友jvm去处理。在Sw...

网友评论

      本文标题:swift-ARC

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