美文网首页
Rx 项目源码分析 - 入门1

Rx 项目源码分析 - 入门1

作者: 貘鸣 | 来源:发表于2017-10-22 14:23 被阅读13次

项目github地址在这里.

下面只是来分析其中的主要内容:

import UIKit
import RxCocoa
import RxSwift

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var searchBar: UISearchBar!
    
    var shownCities = [String]() //
    let allCities = ["New York", "London", "Oslo", "Warsaw", "Berlin", "Praga"] // Our mocked API data source
    let disposeBag = DisposeBag() // Bag of disposables to release them when view is being deallocated
    override func viewDidLoad() {
        super.viewDidLoad()
        setup()
    }
    
    func setup() {
        tableView.dataSource = self
        searchBar
            .rx.text // Observable property thanks to RxCocoa
            .orEmpty // Make it non-optional
            .debounce(0.5, scheduler: MainScheduler.instance) // Wait 0.5 for changes.
            .distinctUntilChanged() // If they didn't occur, check if the new value is the same as old.
            .filter { !$0.isEmpty } // If the new value is really new, filter for non-empty query.
            .subscribe(onNext: { [unowned self] query in // Here we subscribe to every new value, that is not empty (thanks to filter above).
                self.shownCities = self.allCities.filter { $0.hasPrefix(query) } // We now do our "API Request" to find cities.
                self.tableView.reloadData() // And reload table view data.
            })
            .addDisposableTo(disposeBag) // Don't forget to add this to disposeBag. We want to dispose it on deinit.
    }
    
}

// MARK: - UITableViewDataSource
/// Here we have standard data source extension for ViewController
extension ViewController: UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return shownCities.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cityPrototypeCell", for: indexPath)
        cell.textLabel?.text = shownCities[indexPath.row]
        
        return cell
    }
}

这段代码的目的是演示 Rx 中的主体内容: 观察者, Observable 序列, 以及若干操作符.
代码的主要功能是: 当用户在输入框输入想要查询的地址时, 可以根据输入来动态显示对应的城市列表.

首先定义了两个属性, 一个属性用于存放所有的城市allCities, 一个属性用于存放当前显示的城市shownCities.
这里选择的观察时机是在 viewDidLoad 中, 在其中调用 setup() 方法, 下面就主要来看这个方法中的内容:

    func setup() {
        // 指定 tableView 的数据源.
        tableView.dataSource = self

        searchBar
            .rx.text
            .orEmpty
            .debounce(0.5, scheduler: MainScheduler.instance)
            .distinctUntilChanged() // If they didn't occur, check if the new value is the same as old.
            .filter { !$0.isEmpty } // If the new value is really new, filter for non-empty query.
            .subscribe(onNext: { [unowned self] query in // Here we subscribe to every new value, that is not empty (thanks to filter above).
                self.shownCities = self.allCities.filter { $0.hasPrefix(query) } // We now do our "API Request" to find cities.
                self.tableView.reloadData() // And reload table view data.
            })
            .addDisposableTo(disposeBag) // Don't forget to add this to disposeBag. We want to dispose it on deinit.
    }
  1. .rx.text 是 RxCocoa 对 UI 组件的 Rx 扩展属性, 这种属性实际是一种特殊的 Observable 类型 ControlProperty.
  2. orEmpty 操作符也是 RxCocoa 提供的. 其作用是如果遇到 nil, 则解包为默认值, 比如字符串的话就解包为空字符串, 如果非空就进行正常解包.
  3. debounce(dueTime: RxTimeInterval, scheduler: SchedulerType) 操作符是在 RxSwift 中定义的, 它的作用是在序列上按指定时间间隔进行过滤, 只有大于时间间隔的元素才会通过. 而 scheduler 指定计时器是在哪个线程上执行. 而 MainScheduler.instance 获取的是主线程的单例对象, MainScheduler 类似于 DispatchQueue.main.
    而实际上 debounce 的作用是去抖动, 即指定的时长是一个阈值, 只有当超过这个阈值, 而序列没有再次发生变化的时候, 才会让元素继续通过. 比如用户一直很快点击键盘, 此时每次停留的间隔小于 0.5 秒, 则元素一直不会被允许通过. 只有当用户输入暂停的时候, 才会将元素通过.
  4. distinctUntilChanged 操作符也是在 RxSwift 中定义的, 作用是从源序列中生成一个新的序列, 该序列是通过判等来将相同元素过滤掉形成的.
  5. filter 操作符在 RxSwift 中定义, 作用和 swift 的 filter 操作符类似, 进行过滤, 让满足条件的元素通过.
  6. 再下面就是进行观察操作了.

相关文章

网友评论

      本文标题:Rx 项目源码分析 - 入门1

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