Reputation: 454
I have a function that create collection of Publishers:
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
}
In service class I have to method, one for 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)
})
}
and one for stop()
:
func stop() {
anyCancellable?.cancel()
anyCancellable2?.cancel()
}
I've had problem with memory. When collection of publishers is large and I stop()
before whole Publishers.Sequence
is .finshed
memory increase and never release.
Is there a way to completed
Publishers.Sequence
earlier, before Combine iterate over whole collection?
Upvotes: 0
Views: 327
Reputation: 534903
To reclaim the memory, release the pipelines:
func stop() {
anyCancellable?.cancel()
anyCancellable2?.cancel()
anyCancellable = nil
anyCancellable2 = nil
}
Actually you don't need the cancel
calls, because releasing the pipelines does cancel in good order; that is the whole point of AnyCancellable. So you can just say:
func stop() {
anyCancellable = nil
anyCancellable2 = nil
}
Another thing to note is that you are running all your publishers at once. The sequence does not arrive sequentially; the whole sequence is dumped into the flapMap
which starts all the publishers publishing simultaneously. Thus cancelling doesn't do you all that much good. You might want to set the maxPublishers:
on your flatMap
so that backpressure prevents more than some small number of publishers from arriving simultaneously (like for example one at a time).
Upvotes: 1