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

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

我尝试使用可取消袋,但是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
    }

}
diwukongjian 回答:如何正确管理`AnyCancellable`的集合

Apple Combine中的订阅以符合RAII的方式进行范围划分。即取消初始化事件等同于自动丢弃可观察对象的事件。这与RxSwift Disposable不同,后者有时会重现此行为,但并非严格如此。

即使在RxSwift中,如果您丢失了DisposeBag,您的订阅也将被处置,这是一项功能。如果您希望订阅在整个范围内生效,则表示它属于外部范围。

一旦完成订阅,这些实现都不会真正将Disposables从保留树中抛出。

本文链接:https://www.f2er.com/3160490.html

大家都在问