gpt4 book ai didi

swift - 如何正确管理 `AnyCancellable` 的集合

转载 作者:行者123 更新时间:2023-11-28 05:35:44 32 4
gpt4 key购买 nike

除非明确取消,否则我希望所有发布商都执行。我不介意 AnyCancellable 超出范围,但是根据文档,它会在 deinit 上自动调用 cancel,这是不希望的。

我曾尝试使用可取消包,但 AnyCancelable 即使在发布者触发完成后仍继续堆积。

我应该手动管理包吗?我的印象是 store(in: inout Set) 是为了方便管理可取消的实例,但它所做的只是将 AnyCancellable 插入一个集合。

var cancelableSet = Set<AnyCancellable>()

func work(value: Int) -> AnyCancellable {
return Just(value)
.delay(for: .seconds(1), scheduler: DispatchQueue.global(qos: .default))
.map { $0 + 1 }
.sink(receiveValue: { (value) in
print("Got value: \(value)")
})
}

work(value: 1337).store(in: &cancelableSet)

DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(5)) {
print("\(cancelableSet)")
}

到目前为止,我想出了什么,它工作正常,但让我想知道是否 Combine 框架中缺少某些东西,或者它不应该以这种方式使用:

class DisposeBag {
private let lock = NSLock()
private var cancellableSet = Set<AnyCancellable>()

func store(_ cancellable: AnyCancellable) {
print("Store cancellable: \(cancellable)")

lock.lock()
cancellableSet.insert(cancellable)
lock.unlock()
}

func drop(_ cancellable: AnyCancellable) {
print("Drop cancellable: \(cancellable)")

lock.lock()
cancellableSet.remove(cancellable)
lock.unlock()
}
}

extension Publisher {

@discardableResult func autoDisposableSink(disposeBag: DisposeBag, receiveCompletion: @escaping ((Subscribers.Completion<Self.Failure>) -> Void), receiveValue: @escaping ((Self.Output) -> Void)) -> AnyCancellable {
var sharedCancellable: AnyCancellable?

let disposeSubscriber = {
if let sharedCancellable = sharedCancellable {
disposeBag.drop(sharedCancellable)
}
}

let cancellable = handleEvents(receiveCancel: {
disposeSubscriber()
}).sink(receiveCompletion: { (completion) in
receiveCompletion(completion)

disposeSubscriber()
}, receiveValue: receiveValue)

sharedCancellable = cancellable
disposeBag.store(cancellable)

return cancellable
}

}

最佳答案

Apple Combine 中的订阅以符合 RAII 的方式限定范围。 IE。去初始化事件等同于自动处置可观察对象的事件。这与 RxSwift Disposable 相反,在这种情况下,这种行为有时会重现,但并非严格如此。

即使在 RxSwift 中,如果你丢失了一个 DisposeBag,你的订阅也将被丢弃,这是一个特性。如果您希望您的订阅在范围内有效,则意味着它属于外部范围。

一旦订阅完成,这些实现都不会忙于将 Disposables 从保留树中扔出。

关于swift - 如何正确管理 `AnyCancellable` 的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58709220/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com