如何解决使用`Publishers.Sequence`时发生内存泄漏
我具有创建发布者集合的功能:
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
?
解决方法
要回收内存,请释放管道:
func stop() {
anyCancellable?.cancel()
anyCancellable2?.cancel()
anyCancellable = nil
anyCancellable2 = nil
}
实际上,您不需要进行cancel
调用,因为释放管道确实可以按顺序取消;这就是AnyCancellable的重点。所以你可以说:
func stop() {
anyCancellable = nil
anyCancellable2 = nil
}
要注意的另一件事是您正在同时运行所有发布者。序列没有顺序到达; 整个序列被转储到flapMap
中,这将启动所有发布者同时发布。因此取消并不能为您带来很多好处。您可能希望在maxPublishers:
上设置flatMap
,以使背压可以防止同时到达多个发布者(例如一次一个)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。