ios – RxSwift中的双向绑定

我在Rx Swift的示例代码中读取了双向绑定运算符.
func <-> <T>(property: ControlProperty<T>,variable: Variable<T>) -> 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)
}

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

解决方法

感谢提出问题,我花了一些时间来挖掘ControlProperty实现(注意我已经添加一个.debug()调用来跟踪为控件属性生成的值).
public struct ControlProperty<PropertyType> : ControlPropertyType {
    public typealias E = PropertyType

    let _values: Observable<PropertyType>
    let _valueSink: AnyObserver<PropertyType>

    public init<V: ObservableType,S: ObserverType where E == V.E,E == S.E>(values: V,valueSink: S) {
        _values = values.debug("Control property values").subscribeOn(ConcurrentMainScheduler.instance)
        _valueSink = valueSink.asObserver()
    }

    public func on(event: Event<E>) {
        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<Bool>(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 <-> <T>(property: ControlProperty<T>,variable: Variable<T>) -> 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上触发(事件:事件< E>)并将开关值设置为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 (e.g. `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 (e.g. `UISwitch`) -> 
ControlProperty emits event -> 
value assigned to Variable -> 
Variable emits event -> 
ControlProperty receives event -> 
value assigned to underlying control property (e.g. `on` for `UISwitch`)

所以一个简单的解释是:

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

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

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...