swift - 发布者完成时从 AnyCancellable 数组中删除
问题描述
有没有一种好方法来处理数组以在完成/取消时AnyCancellable
删除存储的?AnyCancellable
说我有这个
import Combine
import Foundation
class Foo {
private var cancellables = [AnyCancellable]()
func startSomeTask() -> Future<Void, Never> {
Future<Void, Never> { promise in
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) {
promise(.success(()))
}
}
}
func taskCaller() {
startSomeTask()
.sink { print("Do your stuff") }
.store(in: &cancellables)
}
}
每次taskCaller
调用时,AnyCancellable
都会创建 a 并将其存储在数组中。我想在完成后从数组中删除该实例,以避免内存浪费。
我知道我可以做这样的事情,而不是数组
var taskCancellable: AnyCancellable?
并通过执行以下操作存储可取消的:
taskCancellable = startSomeTask().sink { print("Do your stuff") }
但这会最终创建几个可取消的单并且会污染代码。我不想要这样的课
class Bar {
private var task1: AnyCancellable?
private var task2: AnyCancellable?
private var task3: AnyCancellable?
private var task4: AnyCancellable?
private var task5: AnyCancellable?
private var task6: AnyCancellable?
}
解决方案
我在开发一个生成大量可取消项的应用程序时问自己同样的问题,这些可取消项最终存储在同一个数组中。对于长期存在的应用程序,数组大小可能会变得很大。
即使内存占用很小,那些仍然是对象,它们会消耗堆,这会导致堆碎片。
我找到的解决方案是在发布者完成时删除可取消的:
func consumePublisher() {
var cancellable: AnyCancellable!
cancellable = makePublisher()
.sink(receiveCompletion: { [weak self] _ in self?.cancellables.remove(cancellable) },
receiveValue: { doSomeWork() })
cancellable.store(in: &cancellables)
}
确实,代码不是那么漂亮,但至少没有内存浪费 :)
一些高阶函数可用于使此模式在同一类的其他地方可重用:
func cleanupCompletion<T>(_ cancellable: AnyCancellable) -> (Subscribers.Completion<T>) -> Void {
return { [weak self] _ in self?.cancellables.remove(cancellable) }
}
func consumePublisher() {
var cancellable: AnyCancellable!
cancellable = makePublisher()
.sink(receiveCompletion: cleanupCompletion(cancellable),
receiveValue: { doSomeWork() })
cancellable.store(in: &cancellables)
}
或者,如果您需要支持来完成工作:
func cleanupCompletion<T>(_ cancellable: AnyCancellable) -> (Subscribers.Completion<T>) -> Void {
return { [weak self] _ in self?.cancellables.remove(cancellable) }
}
func cleanupCompletion<T>(_ cancellable: AnyCancellable, completionWorker: @escaping (Subscribers.Completion<T>) -> Void) -> (Subscribers.Completion<T>) -> Void {
return { [weak self] in
self?.cancellables.remove(cancellable)
completionWorker($0)
}
}
func consumePublisher() {
var cancellable: AnyCancellable!
cancellable = makePublisher()
.sink(receiveCompletion: cleanupCompletion(cancellable) { doCompletionWork() },
receiveValue: { doSomeWork() })
cancellable.store(in: &cancellables)
}
推荐阅读
- c++ - 从 char16_t(utf16) 到 utf8 的转换在 Visual Studio 2015 和 2017 中不起作用
- swiftui - 在 SwiftUI 中为 TextField 设置初始值 - 比较新旧值
- elasticsearch - elasticsearch嵌套聚合为空
- c++ - MPI 和分段错误
- c++ - 你如何构造一个可以抛出异常的对象?
- html - Bootstrap - 在 div 中间获取我的 P(具有打字效果)
- php - 在 OSX 上为 PHP 5.6 安装 phpredis 不起作用
- mysql - Mysql - 类似 XML 的表,在同一列中有多个值
- google-sheets - 你如何在谷歌文档的交叉表中求和值
- reactjs - 将 React 类组件转换为功能组件