【问题标题】:ReactiveCocoa subscribe block not called on viewModel in SwiftReactiveCocoa 订阅块未在 Swift 中的 viewModel 上调用
【发布时间】:2014-08-30 19:13:53
【问题描述】:

我正在使用 MVVM 和 ReactiveCocoa 构建一个应用程序来在 viewModel 和 UI 之间进行绑定,但是没有调用视图模型验证信号订阅块。

我的视图模型非常简单和准系统:

class ViewModel: RVMViewModel {
    var name: String = "" {
        willSet {
            println("New Value: \(newValue)")
        }
    }

   required init(){
       super.init()
       let signal = self.rac_valuesForKeyPath("name", observer: self)
       signal.subscribeNext {
           println("Subscribe block: \($0)")
       }
   }
}

在我的视图控制器中,我有以下绑定:

//observe ui and programatic changes
RACSignal.merge([self.nameField.racTextSignal(), self.nameField.rac_valuesForKeyPath("text", observer:self)]).subscribeNext({
     (next) -> Void in
     if let text = next as? String {
         self.viewModel.name = text
     }
})
RAC(self.nameField, "text") = self.viewModel.rac_valuesForKeyPath("name", observer: self)

根据我阅读的here,我让 RAC 宏在 swift 中运行。

现在,在我的视图控制器中的视图绑定中,subscribeNext 块被调用得很好。在我的 viewModel 中,将在 willSet 中打印出新值。但是,当属性首次初始化时,我的 init 块中的信号上的 subscribe 块仅被调用一次。这把我逼疯了,有人有什么想法吗?

【问题讨论】:

    标签: ios mvvm swift reactive-cocoa


    【解决方案1】:

    经过大量实验,我找到了解决方案。通过将信号直接分配给视图模型属性,每次值更改时都会调用订阅块。

    所以不要这样做:

    RACSignal.merge([self.nameField.racTextSignal(), self.nameField.rac_valuesForKeyPath("text", observer:self)]).subscribeNext({
         (next) -> Void in
         if let text = next as? String {
             self.viewModel.name = text
         }    
    })
    

    我这样做了:

    RAC(self.viewModel, "name") <~  RACSignal.merge([self.nameField.racTextSignal(),     
    self.nameField.rac_valuesForKeyPath("text", observer:self)])
    

    我使用this linkRAC&lt;~ 在swift 中工作。

    【讨论】:

      【解决方案2】:

      我还没有解决方案 - 我直到晚上才离开笔记本电脑。但是,尝试在全局范围或实例变量中发出信号...如果这不起作用,请在单例上尝试它作为您明确调用的方法...这些是更多测试,但如果您告诉我它是如何进行的,我们可以一起解决。

      【讨论】:

      • 我最终弄明白了,所以不用担心。
      • @startupthekid 如果你解决了,请发布解决方案,毕竟是这样,我们喜欢在这里分享我们学到的东西:)
      【解决方案3】:

      比被接受的更好的解决方案是简单地标记属性动态:

      dynamic var name: String = "" {
          willSet {
              println("New Value: \(newValue)")
          }
      }
      

      这会启用 Obj-C 级别的 KVO,这通常对仅 Swift 的属性禁用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-16
        • 1970-01-01
        • 2015-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-23
        • 2016-06-26
        相关资源
        最近更新 更多