这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战
前言
_ = Observable
.of(["1", "2", "3"])
.bind(to: tableView.rx.items) { tb , ip, item in
let cell = tb.dequeueReusableCell(withIdentifier: "cell")!
cell.textLabel?.text = item
return cell
}
.disposed(by: disposeBag)
使用 Sequence
数据序列 绑定 tableView.rx
的 items
方法可以快速展示一个 tableView
思考:items
方法是怎样实现实现的,items
方法 必须完成那些功能才能实现 tableView
的展示?
- 必须实现
UITableViewDataSource
- 必须能监听、获取
Sequence
数据序列并保存 - 必须
Sequence
改变能自动刷新TableView
理解 bind(to: )
方法, 展开语法糖
public func bind<R1, R2>(to binder: (Self) -> (R1) -> R2, curriedArgument: R1) -> R2
_ = Observable
.of(["1", "2", "3"])
.bind(to: tableView.rx.items, curriedArgument: { tb , ip, item in
let cell = tb.dequeueReusableCell(withIdentifier: "cell")!
cell.textLabel?.text = item
return cell
})
.disposed(by: disposeBag)
理解 items( _ source: Source) 方法
理解 items(dataSource: DataSource) 方法
简化逻辑后的 items(dataSource: DataSource)
实现
// 设置 TableView 的 UITableViewDataSource 实现 为 dataSource 对象
let unregisterDelegate = RxTableViewDataSourceProxy.installForwardDelegate(dataSource, retainDelegate: true, onProxyForObject: self.base)
// 订阅 source
let reloadTableView = source.subscribe {[weak tableView = self.base] event in
guard let tableView = tableView else {return}
// dataSource: RxTableViewReactiveArrayDataSourceSequenceWrapper<[String]> 更新数据源 即 var itemModels: [Element]?
// tableView.reloadData() 更新 TableView
dataSource.tableView(tableView, observedEvent: event)
}
// 返回一个可销毁对象,在销毁时,同时销毁 unregisterDelegate 和 reloadTableView
return Disposables.create {
unregisterDelegate.dispose()
reloadTableView.dispose()
}
理解 UITableView
、RxTableViewDataSourceProxy
、RxTableViewReactiveArrayDataSource
关系
此关系中的代码片段摘要
获取 RxTableViewDataSourceProxy
对象(DelegateProxyType.swift
/181行)
设置 TableViewDataSource
(DelegateProxyType.swift
/285行)
设置重定向对象 _setForwardToDelegate
(_RXDelegateProxy.m
/95行)
消息重定向 forwardInvocation
(_RXDelegateProxy.m
/117行)
理解 DelegateProxyFactory
如何创建 DelegateProxyType
符合 DelegateProxyType
协议的类创建唯一一个工厂,都保存在 _sharedFactories
字典中
通过 _factories 字典存储 一个类生成 Proxy 对象的方法
在创建工厂对象时,添加创建 Proxy 对象的闭包。后面通过调用闭包创建 Proxy 对象
工厂实现新思路:
通过 字典 和 闭包 实现工厂方法
总结:
-
使用 Rx 设置代理的底层实现
//1. factory.createProxy(for:) 工厂方法创建 RxTableViewDataSourceProxy 对象A open class RxTableViewDataSourceProxy: DelegateProxy<UITableView, UITableViewDataSource>, DelegateProxyType , UITableViewDataSource; //2. 创建具体实现 UITableViewDataSource 的 _RxTableViewReactiveArrayDataSource 的对象B class _RxTableViewReactiveArrayDataSource: NSObject, UITableViewDataSource //3. 对象A 继承_RXDelegateProxy 通过 _setForwardToDelegate 保存 对象B -(void)_setForwardToDelegate:(id __nullable)forwardToDelegate retainDelegate:(BOOL)retainDelegate; //4. 对象A 继承_RXDelegateProxy 通过实现 forwardInvocation 方法将代理消息转发给B @interface _RXDelegateProxy : NSObject open class DelegateProxy<P: AnyObject, D>: _RXDelegateProxy
-
UITableView.rx 的
itmes
方法的实现-
创建 RxTableViewReactiveArrayDataSourceSequenceWrapper 对象
var itemModels: [Element]?
保存数据源let cellFactory: CellFactory
创建 UITableViewCell,并将闭包保留给 items 方法tableView(**_** tableView: , observedElements:)
设置数据源,reloadData()
-
调用 subscribeProxyDataSource, 做3件事
-
使用 installForwardDelegate 方法
- 使用工厂方法创建
RxTableViewDataSourceProxy
对象 - 使用
setForwardToDelegate
方法设置 具体实现UITableViewDataSource
的对象 为RxTableViewReactiveArrayDataSourceSequenceWrapper
对象 - 创建 Disposable 对象,在订阅销毁后释放资源
- 使用工厂方法创建
-
订阅数据源在接收到数据后调用
RxTableViewReactiveArrayDataSourceSequenceWrapper
对象的tableView(**_** tableView: , observedElements:)
方法设置数据源,reloadData() -
创建 Disposable 对象,在订阅销毁后释放资源
-
-