美文网首页Rx
RxSwift源码分析(6)——bind

RxSwift源码分析(6)——bind

作者: 无悔zero | 来源:发表于2020-10-04 15:29 被阅读0次

平常使用RxSwift时经常用到bind函数,意思是绑定,把监听和响应绑定在一起。它使我们的代码变得更加简洁,非常好用,比如:

//tf序列发送响应时,会作用在label上
//相当于监听textField.text变化,然后响应label.text = textField.text
textField.rx.text.bind(to: label.rx.text)
  1. 首先把这句代码拆分为三部分:textField.rx.textlabel.rx.text.bind(to: )
    先来看textField.rx.text,只是一个普通序列:
extension Reactive where Base: UITextField {
    public var text: ControlProperty<String?> {
        return value
    }
    ...
}

再来看label.rx.text,是一个Binder,也是一个序列:

extension Reactive where Base: UILabel {
    public var text: Binder<String?> {
        ...
    }
    ...
}
public struct Binder<Value>: ObserverType {
    ...
}

最后把上面两个序列绑定在一起的就是.bind(to: ).bind(to: )函数找出来有很多个,我们看对应类型的就行:

extension ObservableType {
    @available(*, deprecated, renamed: "bind(to:)")//原来改名了,差点没找到
    public func bindTo<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
        return self.subscribe(observer)
    }
}
  1. .bind(to: )函数内部其实自己进行了subscribe,根据RxSwift核心逻辑,将会调用observeron函数,observer也就是Binder
public struct Binder<Value>: ObserverType {
    ...
    public func on(_ event: Event<Value>) {
        self._binding(event)
    }
    ...
}
  1. self._binding()Binder初始化时保存的私有函数:
public struct Binder<Value>: ObserverType {
    public typealias Element = Value
    
    private let _binding: (Event<Value>) -> Void

    public init<Target: AnyObject>(_ target: Target, scheduler: ImmediateSchedulerType = MainScheduler(), binding: @escaping (Target, Value) -> Void) {
        weak var weakTarget = target

        self._binding = { event in
            switch event {
            case .next(let element):
                _ = scheduler.schedule(element) { element in
                    if let target = weakTarget {
                        binding(target, element)
                    }
                    return Disposables.create()
                }
            case .error(let error):
                bindingError(error)
            case .completed:
                break
            }
        }
    }
    ...
}

我们还可以发现后面的调用会在主线程执行:

  1. 最终在主线程调用binding(target, element),这是Binder初始化时传过来的闭包:
extension Reactive where Base: UILabel {
    /// Bindable sink for `text` property.
    public var text: Binder<String?> {
        return Binder(self.base) { label, text in
            label.text = text
        }
    }
    ...
}
  1. 然后拿到textField.rx.text传递过来的text值,调用label.text = text,这样就完成了绑定。

相关文章

网友评论

    本文标题:RxSwift源码分析(6)——bind

    本文链接:https://www.haomeiwen.com/subject/pfywuktx.html