![](/img/trans.png)
[英]Determining whether a call to `registerUserNotificationSettings` has ever been made in Swift
[英]RxSwift - Determining whether an Observable has been disposed
我試圖讓Publisher
將Observables
出售給其客戶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.