首页 > 解决方案 > 合并 assign(to: on:) 另一个发布者

问题描述

这是一个简单的“下载”类来说明我想要做什么。

class Download {
    
    public var progress: CurrentValueSubject<Double, Never> = CurrentValueSubject<Double, Never>(0)
    
    var subscriptions: Set<AnyCancellable> = []
    
    func start(task: URLSessionTask) {
        task.resume()
        task.progress.publisher(for: \.fractionCompleted).sink { [weak self] (newProgress) in
            self?.progress.send(newProgress)
        }.store(in: &subscriptions)
    }
    
}

我希望能够将进度属性观察者发布者“重新发布”到我当前的价值主题。如您所见,我目前使用该.sink函数进行订阅,然后直接调用CurrentValueSubject发布者。

我希望能够使用像这样的.assign(to:, on:)操作员。

task.progress.publisher(for: \.fractionCompleted).assign(to: \.progress, on: self)

但是,这不起作用.assign(to:),似乎保留用于在 SwiftUI@Published属性上“重新发布”的运算符也不起作用。为什么Combine在这里不辜负它的名字?

标签: iosswiftcombine

解决方案


因为CurrentValueSubject是 a class,所以可以用它作为 的object参数assign(to:on:)。这样,就没有内存泄漏:

class Download {
    
    public let progress: CurrentValueSubject<Double, Never> = .init(0)
    
    var subscriptions: [AnyCancellable] = []
    
    func start(task: URLSessionTask) {
        task.resume()
        task.progress
            .publisher(for: \.fractionCompleted)
            .assign(to: \.value, on: progress)
            .store(in: &subscriptions)
    }
    
}

推荐阅读