Skip to main content
 首页 » 操作系统

ios之ReactiveCocoa 订阅 block 未在 Swift 中的 viewModel 上调用

2024年01月01日49duanxz

我正在构建一个使用 MVVM 和 ReactiveCocoa 的应用程序以在 viewModel 和 UI 之间进行绑定(bind),但是未调用 View 模型验证信号订阅 block 。

我的 View 模型非常简单且准系统:

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)") 
       } 
   } 
} 

在我的 View Controller 中,我有以下绑定(bind):

//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) 

根据我阅读的内容,我让 RAC 宏快速工作 here .

现在,在我的 View Controller 中的 View 绑定(bind)中,subscribeNext block 被调用得很好。在我的 viewModel 中,在 willSet 中打印出新值。但是,当属性首次初始化时,我的 init block 中信号上的订阅 block 仅被调用一次。这让我难以自拔,有人有什么想法吗?

请您参考如下方法:

经过多次试验,我找到了解决方案。通过将信号直接分配给 View 模型属性,每次值更改时都会调用订阅 block 。

所以不要这样做:

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 link得到RAC和 <~快速工作。