Swift5.1学习随笔之内存管理

2020-05-14  本文已影响0人  SAW_

OC一样,swift也是采取基于引用计数的ARC内存管理方案(针对堆空间)

swift中的ARC3种引用:


weakunowned的使用限制
protocol Livable: AnyObject { }
class Person { }

weak var p0: Person?
weak var p1: AnyObject?
weak var p2: Livable? //因为Livable协议遵守AnyObject,所以它只能被类遵守

unowned var p10: Person?
unowned var p11: AnyObject?
unowned var p12: Livable?

Autoreleasepool自动释放池

在需要缓解内存压力的地方,使用autoreleasepool

autoreleasepool {
    print("kkkk")
}

循环引用

闭包的循环引用
class Person {
    var fn: (() -> ())?
    func run() { print("Person run") }
    deinit { print("Person deinit") }
}
func test() {
    let p = Person()
    p.fn = { p.run() }
}
test()

通过汇编可以看到,进行了retain操作,导致计数器+1,最终release之后,计数器还是1Person对象没有释放:


尝试注释掉p.fn = { p.run() }这行调用,再看下断点汇编:这时候计算器已经是0了,Person对象被销毁

因为闭包表达式用到了外面的对象,产生了强引用,导致无法释放对象。
func test() {
    let p = Person()
    p.fn = {
        [weak p] in
        p?.run()
    }
}
test()
p.fn = {
     [unowned p] in
     p.run()
}

甚至可以自定义名称:

p.fn = {
      [weak wp = p, unowned up = p, a = 10 + 20] in
      wp?.run()
}
class Person {
    lazy var fn: (() -> ()) = {
        [weak self] in
        self?.run()
    }
    func run() { print("Person run") }
    deinit { print("Person deinit") }
}
func test() {
    var p = Person()
    p.fn()
}
test()
class Person {
    var age: Int = 0
    lazy var getAge: Int = {
        self.age
    }()
    deinit { print("Person deinit") }
}
上一篇 下一篇

猜你喜欢

热点阅读