在deinit 上,您的 ViewController 将从内存中删除。它的所有实例变量都将被释放。
Combine > Publisher > assign(to:on:) 的文档说:
一个 AnyCancellable 实例。当你没有时在这个实例上调用 cancel()
不再希望发布者自动分配属性。
取消初始化此实例也会取消自动分配。
1 - 我应该在 deinit 中取消订阅吗?还是它会自动完成这项工作?
您不需要,它会自动完成这项工作。当您的 ViewController 被释放时,实例变量 bag 也将被释放。由于没有更多引用您的AnyCancellable,因此作业将结束。
2 - 如果是这样,我如何取消所有已存储的订阅?
并非如此。但通常您可能有一些订阅要开始和停止,例如,viewWillAppear/viewDidDissapear。在这种情况下,您的 ViewController 仍在内存中。
因此,在viewDidDissappear 中,您可以按照您的猜测执行bag.removeAll()。这将删除引用并停止分配。
您可以运行以下代码来查看 .removeAll() 的实际效果:
var bag = Set<AnyCancellable>()
func testRemoveAll() {
Timer.publish(every: 1, on: .main, in: .common).autoconnect()
.sink { print("===== timer: \($0)") }
.store(in: &bag)
Timer.publish(every: 10, on: .main, in: .common).autoconnect()
.sink { _ in self.bag.removeAll() }
.store(in: &bag)
}
第一个计时器将每隔一秒触发一次并打印出一行。第二个计时器将在 10 秒后触发,然后调用 bag.removeAll()。然后两个计时器发布者都将停止。
https://developer.apple.com/documentation/combine/publisher/3235801-assign