RxSwift中的双向绑定

我在RxSwift的示例代码中读取了双向绑定运算符。

func  (property: ControlProperty, variable: Variable) -> Disposable { let bindToUIDisposable = variable.asObservable() .bindTo(property) let bindToVariable = property .subscribe(onNext: { n in variable.value = n }, onCompleted: { bindToUIDisposable.dispose() }) return StableCompositeDisposable.create(bindToUIDisposable, bindToVariable) } 

property改变时,它将通知变量,并设置变量的值,当设置变量的值时,它将通知属性。 我认为这将导致无休止的循环……

感谢提出问题,我花了一些时间来挖掘ControlProperty实现(注意我已经添加了一个.debug()调用来跟踪为控件属性生成的值)。

 public struct ControlProperty : ControlPropertyType { public typealias E = PropertyType let _values: Observable let _valueSink: AnyObserver public init(values: V, valueSink: S) { _values = values.debug("Control property values").subscribeOn(ConcurrentMainScheduler.instance) _valueSink = valueSink.asObserver() } public func on(event: Event) { switch event { case .Error(let error): bindingErrorToInterface(error) case .Next: _valueSink.on(event) case .Completed: _valueSink.on(event) } } } 

我的测试设置如下,我删除了所有定位在这里以缩短它:

 import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { let variable = Variable(false); let bag = DisposeBag(); override func loadView() { super.loadView() let aSwitch = UISwitch(); view.addSubview(aSwitch) (aSwitch.rx_value <-> variable).addDisposableTo(bag); let button = UIButton(); button.rx_tap.subscribeNext { [weak self] in self?.variable.value = true; }.addDisposableTo(bag) view.addSubview(button); } } infix operator <-> { } func <-> (property: ControlProperty, variable: Variable) -> Disposable{ let bindToUIDisposable = variable.asObservable().debug("Variable values in bind") .bindTo(property) let bindToVariable = property .debug("Property values in bind") .subscribe(onNext: { n in variable.value = n }, onCompleted: { bindToUIDisposable.dispose() }) return StableCompositeDisposable.create(bindToUIDisposable, bindToVariable) } 

现在结果。 首先我们尝试点击按钮,该按钮应该将变量设置为true 。 这将触发ControlProperty on(event: Event)并将switch值设置为true

 2016-05-28 12:24:33.229: Variable values in bind -> Event Next(true) // value flow value assigned to Variable -> Variable emits event -> ControlProperty receives event -> value assigned to underlying control property (eg `on` for `UISwitch`) 

接下来让我们触发开关。 正如我们所看到的,控件生成一个事件,作为UIControlEventValueChanged的结果,它通过ControlProperty上的_values传递,然后将其值分配给Variable值,如上例所示。 但是没有循环,因为更新到Variable值不会触发交换机上的控制事件。

 2016-05-28 12:29:01.957: Control property values -> Event Next(false) 2016-05-28 12:29:01.957: Property values in bind -> Event Next(false) 2016-05-28 12:29:01.958: Variable values in bind -> Event Next(false) // value flow trigger the state of control (eg `UISwitch`) -> ControlProperty emits event -> value assigned to Variable -> Variable emits event -> ControlProperty receives event -> value assigned to underlying control property (eg `on` for `UISwitch`) 

所以一个简单的解释是:

  • 一旦触发某种UIControlEvent就会发出控件的值
  • 当值直接分配给控件属性时,控件不会触发更改事件,因此没有循环。

希望它有所帮助,抱歉有点凌乱的解释 – 我通过实验找到了它)

我相信你可以使用bindTo🙂。 以下是ControlProperty <-> VariableVariable <-> Variable

 infix operator <-> { precedence 130 associativity left } func <->(property: ControlProperty, variable: Variable) -> Disposable { let variableToProperty = variable.asObservable() .distinctUntilChanged() .bindTo(property) let propertyToVariable = property .distinctUntilChanged() .bindTo(variable) return StableCompositeDisposable.create(variableToProperty, propertyToVariable) } func <->(left: Variable, right: Variable) -> Disposable { let leftToRight = left.asObservable() .distinctUntilChanged() .bindTo(right) let rightToLeft = right.asObservable() .distinctUntilChanged() .bindTo(left) return StableCompositeDisposable.create(leftToRight, rightToLeft) } 

ControlProperty <-> Variable示例(例如UITextFieldUITextView )位于RxSwiftPlayer项目中

 // Example of Variable <-> Variable let disposeBag = DisposeBag() let var1 = Variable(1) let var2 = Variable(2) (var1 <-> var2).addDisposableTo(disposeBag) var1.value = 10 print(var2.value) // 10 var2.value = 20 print(var1.value) // 20