RxSwift-如何用协议实现一个命名空间
RxSwift-如何用协议实现一个命名空间
RxSwift简介
RxSwift是一个函数响应式框架,使用到的是FRP(函数响应式编程)编程思想。它是通过构建函数操作数据序列,然后对这些序列做出响应的编程方式。基本的使用可以参考官方的RxSwift中文文档。
rx是什么?
在RxSwift的使用过程中我们经常可以看到以下代码:
cameraButton.rx.tap |
其中rx
具体是什么呢?我们点击进去,找到以下源码
/// A type that has reactive extensions. |
rx
是protocol ReactiveCompatible
的属性,static var rx
是类变量,var rx
是实例变量,变量类型为Reactive<ReactiveBase>
。associatedtype
关键字是为protocol
提供泛型功能。Reactive
遵循了ReactiveCompatible
协议,那么Reactive
的泛型就会替代ReactiveBase
。- 在Swift中,我们可以通过
extension protocol
来为协议的属性或者方法提供默认实现。
public struct Reactive<Base: AnyObject> { |
Reactive
结构体有一个base
属性,存储了当前的实例对象,方便调用Base
的实例方法。
核心逻辑
定义一个协议
ReactiveCompatible
,协议拥有Reactive
类型的属性rx
。NSObject
遵循协议ReactiveCompatible
,这样所有的类就都拥有了属性rx
。// NSObject遵循ReactiveCompatible协议,保证所有类都有rx属性
extension NSObject: ReactiveCompatible { }我们通常通过以下方式来使用
RxSwift
。当执行button.rx
后,我们可以看到返回的类型为Reactive<UIButton>
,所以我们要添加tap
属性,扩展的应该是Reactive
类。// RxSwift具体用法
let button = UIButton()
button.rx.tap
.subscribe(onNext: {
print("UIButton Tapped")
})
.disposed(by: disposeBag)扩展
Reactive
,添加tap
属性,where Base: UIButton
表示此属性只是给UIButton
添加。// 如果要对UIButton新增属性或者方法,是对Reactive结构体进行扩展,where语法限定扩展的属性或者方法只属于UIButton
extension Reactive where Base: UIButton {
public var tap: ControlEvent<Void> {
controlEvent(.touchUpInside)
}
}
补充: Reactive结构体base属性的作用
在URLSession
扩展方法中,我们可以看到base
属性的作用,主要是在调用URLSession
自身的方法时用到。
extension Reactive where Base: URLSession { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 雷军的博客!