在尝试使用Combine 分配值时,我看到了一些我不太理解的结构与类行为。
代码:
import Foundation
import Combine
struct Passengers {
var women = 0
var men = 0
}
class Controller {
@Published var passengers = Passengers()
var cancellables = Set<AnyCancellable>()
let minusButtonTapPublisher: AnyPublisher<Void, Never>
init() {
// Of course the real code has a real publisher for button taps :)
minusButtonTapPublisher = Empty<Void, Never>().eraseToAnyPublisher()
// Works fine:
minusButtonTapPublisher
.map { self.passengers.women - 1 }
.sink { [weak self] value in
self?.passengers.women = value
}.store(in: &cancellables)
// Doesn't work:
minusButtonTapPublisher
.map { self.passengers.women - 1 }
.assign(to: \.women, on: passengers)
.store(in: &cancellables)
}
}
我得到的错误是
Key path value type 'ReferenceWritableKeyPath<Passengers, Int>' cannot be converted to contextual type 'WritableKeyPath<Passengers, Int>'
.使用
sink
的版本而不是 assign
工作正常,当我转动时 Passengers
进类后,assign
版本也可以正常工作。我的问题是:为什么它只适用于一个类?这两个版本(sink 和assign)最后真的做同样的事情,对吧?他们都更新了 women
属性(property)在 passengers
.(当我将
Passengers
更改为一个类时,sink
版本不再有效。)
最佳答案
实际上它是明确记录的 - 将发布者中的每个元素分配给对象上的属性。这是 Assign
的功能、设计订阅者 - 仅适用于引用类型。
extension Publisher where Self.Failure == Never {
/// Assigns each element from a Publisher to a property on an object.
///
/// - Parameters:
/// - keyPath: The key path of the property to assign.
/// - object: The object on which to assign the value.
/// - Returns: A cancellable instance; used when you end assignment of the received value. Deallocation of the result will tear down the subscription stream.
public func assign<Root>(to keyPath: ReferenceWritableKeyPath<Root, Self.Output>, on object: Root) -> AnyCancellable
}
关于swift - 结合:不能将 `.assign` 与结构一起使用 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61056787/