内存管理与AnyCancellable的理解

所有的发布订阅返回都是一个Cancellable的对象,正确使用Cancellable与内存管理对程序的稳定性至关重要

步骤一: 定义类

class MyClass {
    var cancellable: Cancellable? = nil
    var variable: Int = 0 {
        didSet {
            print("MyClass object.variable = \(variable)")
        }
    }

    init(subject: PassthroughSubject<Int,Never>) {
        cancellable = subject.sink { value in
            // Note that we are introducing a retain cycle on `self`
            // on purpose, by not using `weak` or `unowned`
            self.variable += value
        }
    }

    deinit {
        print("MyClass object deallocated")
    }
}

步骤二: 定义数据定时发送方法

func emitNextValue(from values: [Int], after delay: TimeInterval) {
    DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
        var array = values
        subject.send(array.removeFirst())
        if !array.isEmpty {
            emitNextValue(from: array, after: delay)
        }
    }
}

步骤三:内存管理错误

由于object内部的订阅者依旧活跃并可消费消息

let subject = PassthroughSubject<Int,Never>()
var object: MyClass? = MyClass(subject: subject)

emitNextValue(from: [1,2,3,4,5,6,7,8], after: 0.5)

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
    print("Nullify object")
    object = nil
}

输出:

MyClass object.variable = 1
MyClass object.variable = 3
MyClass object.variable = 6
Nullify object
MyClass object.variable = 10
MyClass object.variable = 15
MyClass object.variable = 21
MyClass object.variable = 28
MyClass object.variable = 36

步骤四:修复

Cancellable取消订阅后,类实例完成了deinit销毁,并正确进行了类销毁
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
    print("Nullify object")
    object?.cancellable = nil
    object = nil
}

输出:
MyClass object.variable = 1
MyClass object.variable = 3
MyClass object.variable = 6
Nullify object
MyClass object deallocated

Made with in Shangrao,China By 老雷

Copyright © devler.cn 1987 - Present

赣ICP备19009883号-1