IOS 超级无敌程序员iOS大咖说

Swift - RxSwift的使用详解2(响应式编程与传统式编

2018-03-07  本文已影响803人  八级大狂风AM

在详细介绍 RxSwift 相关的知识点之前,我想先通过一个样例演示下 RxSwift 到底能做什么,好让大家能够对其有一个直观的了解。

三、两种编程方式的比较样例

1,效果图

这里我以最常见的 tableView 数据展示功能为例作为演示。后面分别使用传统写法,以及使用 RxSwift 响应式写法来实现,大家可以比较下它们的区别。

2,准备工作

首先我们创建一个 Music 的结构体,用来保存歌曲名称、歌手名字。此外它还遵循 CustomStringConvertible 协议,方便我们输出调试。

import UIKit
 
//歌曲结构体
struct Music {
    let name: String //歌名
    let singer: String //演唱者
     
    init(name: String, singer: String) {
        self.name = name
        self.singer = singer
    }
}
 
//实现 CustomStringConvertible 协议,方便输出调试
extension Music: CustomStringConvertible {
    var description: String {
        return "name:\(name) singer:\(singer)"
    }
}

3,过去我们会这么做(传统式编程)

(1)首先写一个 ViewModel

import Foundation
 
//歌曲列表数据源
struct MusicListViewModel {
    let data = [
        Music(name: "无条件", singer: "陈奕迅"),
        Music(name: "你曾是少年", singer: "S.H.E"),
        Music(name: "从前的我", singer: "陈洁仪"),
        Music(name: "在木星", singer: "朴树"),
    ]
}

(2)视图控制器代码(ViewController.swift)

import UIKit
import RxSwift
 
class ViewController: UIViewController {
 
    //tableView对象
    @IBOutlet weak var tableView: UITableView!
     
    //歌曲列表数据源
    let musicListViewModel = MusicListViewModel()
     
    override func viewDidLoad() {
        super.viewDidLoad()
         
        //设置代理
        tableView.dataSource = self
        tableView.delegate = self
    }
}
 
extension ViewController: UITableViewDataSource {
    //返回单元格数量
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return musicListViewModel.data.count
    }
     
    //返回对应的单元格
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
        -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "musicCell")!
        let music = musicListViewModel.data[indexPath.row]
        cell.textLabel?.text = music.name
        cell.detailTextLabel?.text = music.singer
        return cell
    }
}
 
extension ViewController: UITableViewDelegate {
    //单元格点击
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("你选中的歌曲信息【\(musicListViewModel.data[indexPath.row])】")
    }
}

4,现在使用 RxSwift 进行改造(响应式编程)

(1)对 ViewModel 做些修改

import RxSwift
 
//歌曲列表数据源
struct MusicListViewModel {
    let data = Observable.just([
        Music(name: "无条件", singer: "陈奕迅"),
        Music(name: "你曾是少年", singer: "S.H.E"),
        Music(name: "从前的我", singer: "陈洁仪"),
        Music(name: "在木星", singer: "朴树"),
    ])
}

(2)视图控制器代码(ViewController.swift)

代码的简单说明:

  • DisposeBag:作用是 Rx 在视图控制器或者其持有者将要销毁的时候,自动释法掉绑定在它上面的资源。它是通过类似“订阅处置机制”方式实现(类似于 NotificationCenterremoveObserver)。
  • rx.items(cellIdentifier:):这是 Rx 基于 cellForRowAt 数据源方法的一个封装。传统方式中我们还要有个 numberOfRowsInSection 方法,使用 Rx 后就不再需要了(Rx 已经帮我们完成了相关工作)。
  • rx.modelSelected: 这是 Rx 基于 UITableView委托回调方法 didSelectRowAt 的一个封装。
import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
 
    //tableView对象
    @IBOutlet weak var tableView: UITableView!
     
    //歌曲列表数据源
    let musicListViewModel = MusicListViewModel()
     
    //负责对象销毁
    let disposeBag = DisposeBag()
     
    override func viewDidLoad() {
        super.viewDidLoad()
         
        //将数据源数据绑定到tableView上
        musicListViewModel.data
            .bind(to: tableView.rx.items(cellIdentifier:"musicCell")) { _, music, cell in
                cell.textLabel?.text = music.name
                cell.detailTextLabel?.text = music.singer
            }.disposed(by: disposeBag)
         
        //tableView点击响应
        tableView.rx.modelSelected(Music.self).subscribe(onNext: { music in
            print("你选中的歌曲信息【\(music)】")
        }).disposed(by: disposeBag)
    }
}

RxSwift使用详解系列
原文出自:www.hangge.com转载请保留原文链接

上一篇 下一篇

猜你喜欢

热点阅读