我具有创建发布者集合的功能:
func publishers(from text: String) -> [AnyPublisher<SignalToken, Never>] {
let signalTokens: [SignalToken] = translate(from: text)
var delay: Int = 0
let signalPublishers: [AnyPublisher<SignalToken, Never>] = signalTokens.map { token in
let publisher = Just(token)
.delay(for: .milliseconds(delay), scheduler: DispatchQueue.main)
.eraseToAnyPublisher()
delay += token.delay
return publisher
}
return signalPublishers
}
在服务类中,我必须使用方法,其中一个用于play()
:
func play(signal: String) {
anyCancellable = signalTokenSubject.sink(receiveValue: { token in print(token) }
anyCancellable2 = publishers(from: signal)
.publisher
.flatMap { $0 }
.subscribe(on: DispatchQueue.global())
.sink(receiveValue: { [weak self] token in
self?.signalTokenSubject.send(token)
})
}
和一个stop()
:
func stop() {
anyCancellable?.cancel()
anyCancellable2?.cancel()
}
我的记忆有问题。如果发布者的数量很大,并且在整个stop()
之前我Publishers.Sequence
是.finshed
,则内存增加并且永远不会释放。
在合并对整个集合进行迭代之前,是否有办法提前completed
Publishers.Sequence
?
答案 0 :(得分:1)
要回收内存,请释放管道:
func stop() {
anyCancellable?.cancel()
anyCancellable2?.cancel()
anyCancellable = nil
anyCancellable2 = nil
}
实际上,您不需要进行cancel
调用,因为释放管道确实可以按顺序取消;这就是AnyCancellable的重点。所以你可以说:
func stop() {
anyCancellable = nil
anyCancellable2 = nil
}
要注意的另一件事是您正在同时运行所有发布者。序列没有顺序到达; 整个序列被转储到flapMap
中,这将启动所有发布者同时发布。因此取消并不能为您带来很多好处。您可能希望在maxPublishers:
上设置flatMap
,以使背压可以防止同时到达多个发布者(例如一次一个)。