Swift 发布服务器完成时从anyCancelable数组中删除

Swift 发布服务器完成时从anyCancelable数组中删除,swift,combine,Swift,Combine,是否有一种处理anycancelable数组的好方法,可以在存储的anycancelable完成/取消后将其删除 说我有这个 导入联合收割机 进口基金会 福班{ 私有var cancelables=[anycancelables]() func startSomeTask()->Future{ 未来{ DispatchQueue.main.asyncAfter(截止日期:.now()+秒(2)){ 承诺(.success(())) } } } func taskCaller(){ startSo

是否有一种处理
anycancelable
数组的好方法,可以在存储的
anycancelable
完成/取消后将其删除

说我有这个

导入联合收割机
进口基金会
福班{
私有var cancelables=[anycancelables]()
func startSomeTask()->Future{
未来{
DispatchQueue.main.asyncAfter(截止日期:.now()+秒(2)){
承诺(.success(()))
}
}
}
func taskCaller(){
startSomeTask()
.sink{print(“做你的事”)}
.store(在:&可取消项中)
}
}
每次调用
taskCaller
,都会创建一个
anycancelable
,并将其存储在数组中。 我希望在该实例完成后将其从阵列中删除,以避免内存浪费

我知道我可以这样做,而不是数组

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?

}

这是一个好主意,但实际上没有什么可以删除的。当完成(finish或cancel)进入管道时,管道上的所有内容都会有序地取消订阅,所有类(订阅对象)都会被取消分配,等等。因此,在你的未来释放出价值或失败后,唯一有意义的“活着”的东西是管道末端的水槽,它很小

要查看此信息,请运行以下代码

for _ in 1...100 {
    self.taskCaller()
}

并使用工具跟踪您的分配。果不其然,之后会有100个任意可取消对象,总计3KB。没有未来;
startSomeTask
中的其他对象都不存在了,它们很小(48字节),如果存在也没关系。

我在开发一个生成大量可取消内容的应用程序时问了自己同样的问题,这些内容最终存储在同一个数组中。对于长寿命的应用程序,阵列大小可能会变得巨大

即使内存占用很小,这些仍然是对象,它们消耗堆,这可能导致堆在时间上出现碎片

我找到的解决方案是在发布服务器完成后删除可取消项:

func-consumerpublisher(){
var可取消:任何可取消!
cancelable=makePublisher()
.sink(receiveCompletion:{[weak self]uu in self?.cancelables.remove(cancelables)},
receiveValue:{doSomeWork()})
可取消。存储(位于:&可取消)
}
的确,代码没有那么漂亮,但至少没有内存浪费:)

一些高阶函数可用于使此模式在同一类的其他位置可重用:

func cleanupCompletion(\uCancelable:anyCancelable)->(Subscribers.Completion)->Void{
返回{[weake self]\在self?.cancelables.remove(cancelables)}
}
func publisher(){
var可取消:任何可取消!
cancelable=makePublisher()
.水槽(接收完成:清理完成(可取消),
receiveValue:{doSomeWork()})
可取消。存储(位于:&可取消)
}
或者,如果您还需要支持来完成工作:

func cleanupCompletion(\uCancelable:anyCancelable)->(Subscribers.Completion)->Void{
返回{[weake self]\在self?.cancelables.remove(cancelables)}
}
func cleanupCompletion(uCancelable:anyCancelable,completionWorker:@escaping(Subscribers.Completion)->Void)->(Subscribers.Completion)->Void{
返回{[弱自我]in
自我?.可取消。删除(可取消)
completionWorker($0)
}
}
func publisher(){
var可取消:任何可取消!
cancelable=makePublisher()
.sink(receiveCompletion:cleanupCompletion(可取消){docCompletionWork()},
receiveValue:{doSomeWork()})
可取消。存储(位于:&可取消)
}

你认为我只是想得太多了吗?我也正打算这么做,谢谢,我想我还是忽略它吧。“过早优化是万恶之源。”:)