我在RxSwift的示例代码中阅读了双向绑定(bind)运算符。
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)
}
当
property
更改时,它将通知变量,并设置变量的值,而在设置变量的值时,它将通知属性。我认为这将导致无休止的循环... 最佳答案
感谢提出这个问题,我花了一些时间研究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)
}
}
}
我的测试设置如下,我删除了此处的所有 View 以使其更短:
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上的on(event: Event<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
,就会发出控件的值希望对您有所帮助,抱歉给您带来一些困惑的解释-我已经通过实验找到了)