如果我已将可取消集存储到 ViewController 中:
private var bag = Set<AnyCancellable>()
其中包含多个订阅。1 - 我应该在 deinit 中取消订阅吗?或者它会自动完成工作?
2 - 如果是这样,我如何取消所有存储的订阅?
bag.removeAll() is enough?
还是我应该遍历集合并一一取消所有订阅?for sub in bag {
sub.cancel()
}
Apple 表示订阅一直有效,直到存储的 AnyCancellable 在内存中。所以我想用 bag.removeAll()
解除分配可取消的应该够了吧?
最佳答案
上 deinit
您的 ViewController 将从内存中删除。它的所有实例变量都将被释放。Combine > Publisher > assign(to:on:)
的文档说:
An AnyCancellable instance. Call cancel() on this instance when you no longer want the publisher to automatically assign the property. Deinitializing this instance will also cancel automatic assignment.
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
关于iOS Swift 组合 : cancel a Set<AnyCancellable>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59002502/