簡體   English   中英

RxSwift - 確定 Observable 是否已被釋放

[英]RxSwift - Determining whether an Observable has been disposed

我試圖讓PublisherObservables出售給其客戶Consumer ,以確定其消費者之一何時處置了其Observable

煩人。 我的代碼運行良好,直到我從Consumer代碼中刪除了一個 RxSwift .debug

有沒有其他方法可以讓這個工作?

private class Subscriber {
    var ids: [Int]
    // This property exists so I can watch whether the observable has 
    // gone nil (which I though would happen when its been disposed, but it 
    // seems to happen immediately)
    weak var observable: Observable<[Updates]>?
}
class Publisher {
    private let relay: BehaviorRelay<[Int: Updates]> 
    private var subscribers: [Subscriber] = []

    func updatesStream(for ids: [Int]) -> Observable<[Updates]> {
        let observable = relay
           .map { map in
               return map
                   .filter { ids.contains($0.key) }
                   .map { $0.value }
           }
           .filter { !$0.isEmpty }
           .asObservable()

        let subscriber = Subscriber(ids: ids, observable: observable)
        subscribers.append(subscriber)
        return observable
    }

    private func repeatTimer() {
        let updates: [Updates] = ....

        // I need to be able to determine at this point whether the subscriber's 
        // observable has been disposed of, so I can remove it from the list of
        // subscribers. However `subscriber.observable` is always nil here.
        // PS: I am happy for this to happen before the `repeatTimer` func fires
        subscribers.remove(where: { subscriber in
            return subscriber.observable == nil
        })

        relay.accept(updates)
    }
}

class Client {

    private var disposeBag: DisposeBag?
    private let publisher = Publisher()

    func startWatching() {
        let disposeBag = DisposeBag()
        self.disposeBag = disposeBag

        publisher
            // with the `.debug` below things work OK, without it the 
            ///`Publisher.Subscriber.observable` immediately becomes nil
            //.debug("Consumer") 
            .updatesStream(for: [1, 2, 3])
            .subscribe(onNext: { values in
                print(values)
            })
           .disposed(by: disposeBag)
    }

    func stopWatching() {
        disposeBag = nil
    }
}

我認為這是一個非常糟糕的主意,但它解決了所要求的問題......如果我不得不將此代碼放在我的一個項目中,我會非常擔心競爭條件......

struct Subscriber {
    let ids: [Int]
    var subscribeCount: Int = 0
    let lock = NSRecursiveLock()
}

class Publisher {
    private let relay = BehaviorRelay<[Int: Updates]>(value: [:])
    private var subscribers: [Subscriber] = []

    func updatesStream(for ids: [Int]) -> Observable<[Updates]> {
        var subscriber = Subscriber(ids: ids)
        let observable = relay
            .map { map in
                return map
                    .filter { ids.contains($0.key) }
                    .map { $0.value }
            }
            .filter { !$0.isEmpty }
            .do(
                onSubscribe: {
                    subscriber.lock.lock()
                    subscriber.subscribeCount += 1
                    subscriber.lock.unlock()
                },
                onDispose: {
                    subscriber.lock.lock()
                    subscriber.subscribeCount -= 1
                    subscriber.lock.unlock()
                })
                .asObservable()

                subscribers.append(subscriber)
                return observable
                }

    private func repeatTimer() {
        subscribers.removeAll(where: { subscriber in
            subscriber.subscribeCount == 0
        })
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM