我想和未来做一个异步的工作。但是下面的.sink()闭包从未被调用。看来,未来的实例在被调用之后就被释放了。
Future<Int, Never> { promise in
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
promise(.success(1))
}
}
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: { completion in
print(completion)
}, receiveValue: {
print($0)
})因此,我将.subscribe(Subscribers.Sink())替换为.sink()闭包,如下所示。效果很好。但问题是我不明白为什么它能正常工作。)(在我看来是一样的。这两种密码有什么区别?什么时候可以使用.sink(),什么时候可以不使用?
Future<Int, Never> { promise in
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
promise(.success(1))
}
}
.receive(on: DispatchQueue.main)
.subscribe(Subscribers.Sink(receiveCompletion: { completion in
print(completion)
}, receiveValue: {
print($0)
}))提前谢谢。
发布于 2020-04-15 13:36:14
.sink操作符做了三件事:
Subscribers.Sink。Publisher上调用subscribe,传递它创建的Sink。H 110它创建一个AnyCancellable,它在销毁时取消Sink。它返回对此AnyCancellable.的引用。
AnyCancellable是一个引用计数对象.当最后一次对AnyCancellable的引用被销毁时,AnyCancellable本身就被销毁。当时,它调用自己的cancel方法。
在第一个示例中,您没有保存由AnyCancellable返回的.sink。因此Swift会立即销毁它,这意味着它会立即取消订阅。一秒钟后,您的asyncAfter闭包调用promise,但是订阅已经被取消,因此您的receiveValue闭包不会被调用。
在第二个示例中,由于要创建Subscribers.Sink对象并亲自将其传递给subscribe,所以没有创建用于包装Sink的AnyCancellable。所以没有什么东西会自动破坏订阅。一秒钟后,asyncAfter闭包调用promise。由于订阅没有被销毁,它仍然存在,所以调用receiveValue闭包,然后调用receiveCompletion闭包。
因此,这实际上是一个非常有趣的使用Subscribers.Sink而不是.sink运算符。使用.sink时,必须保存返回的AnyCancellable,否则订阅立即被取消。但是,通过直接使用Subscribers.Sink,您可以创建一个持续到完成的订阅,并且您不需要保存任何东西。当订阅完成(使用.finished或.failure)时,Sink会丢弃Subscription,这会中断保持其活力的保留周期,因此Sink和Subscription也会被销毁,没有留下内存泄漏。
https://stackoverflow.com/questions/61216852
复制相似问题