swift - 结合:不能将 `.assign` 与结构一起使用 - 为什么?

标签 swift combine

在尝试使用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/

相关文章:

swift - 如何在 Swift 中为 performFetchWithCompletionHandler 调用 completionHandler

swift - ios8 swift : how can i access/edit/remove default/private inputAccessoryView height constraint '_UIKBAutolayoutHeightConstraint'

swift - stringByAppendingString 不返回修改后的字符串

Swift Combine 的 CombineLatest 不会响应对其发布者之一的更新而触发

ios - 如何告诉 SwiftUI View 绑定(bind)到嵌套的 Observable 对象

SwiftUI @Binding 不刷新 View

swift - 在 Swift 中编写自定义访问运算符

ios - 当我在 Telegram 上分享时,如何更改 TintColor 栏按钮项目?

SwiftUI:无法推断通用参数 'Subject'

swift - 为什么 URLSession.DataTaskPublisher 不发布值?