iOS Swift 组合 : cancel a Set<AnyCancellable>

标签 ios swift swiftui ios13 combine

如果我已将可取消集存储到 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/

相关文章:

ios - 为什么我的 UITableViewCells 不显示信息?

ios - 什么时候使用?、!、无或惰性?

Swift:转换到新场景后释放 GameScene?

swift - Swift(UI) 中的 "some"关键字是什么?

ios - 在其他 View 中更新核心数据属性时,SwiftUI 列表不会更新

带有 Overlay 的 SwiftUI UIView 取消触摸

ios - GLSL:是否可以创建包含中心像素的单色区域的蒙版?

ios - 记住我使用 UISwitch 和 NSUserDefaults ios 的功能

javascript - 获取 WKWebView 的内容高度不正确

ios - 使用 Apple Maps 确定用户是否在多边形区域之外