内存管理与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