Вот простой класс «Загрузить», чтобы проиллюстрировать, что я хочу сделать.
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 не соответствует своему названию?





Вам нужно присвоить ценность предмета, а не сам предмет. Однако стоит отметить, что assign(to: ..., on: self) приводит к утечке памяти ??♀️.
func start(task: URLSessionTask) {
task.resume()
task.progress
.publisher(for: \.fractionCompleted)
.assign(to: \.progress.value, on: self)
.store(in: &subscriptions)
}
Спасибо! Это то, что я искал. Мне известно об утечке памяти в этой функции. Я исключил эту деталь, чтобы вопрос был узким. Я использую функцию .assignToNoRetain, описанную в этой ветке. stackoverflow.com/questions/57980476/…
Поскольку CurrentValueSubject - это 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)
}
}
Спасибо, Роб. Это лучшее решение.
Субъект сам по себе является оператором! Вы можете подписаться на него напрямую на издателя прогресса, без приёма и назначения.