RxSwift的介绍与使用

目录

一、RxSwift 简介

RxSwift 是 Swift 语言的响应式编程框架,基于 ReactiveX(Reactive Extensions) 标准实现。它通过 观察者模式函数式编程 思想,简化异步事件处理和数据流管理,特别适合处理 UI 事件、网络请求、数据绑定等场景。

二、核心概念

  1. Observable:数据源/事件流(被观察者)
  2. Observer:订阅者(观察者)
  3. Operator:操作符(转换/过滤/组合数据流)
  4. Scheduler:线程调度器(管理操作执行线程)
  5. Disposable:资源管理(取消订阅)

三、基础使用示例

3.1、创建 Observable & 订阅事件

swift 复制代码
import RxSwift

let disposeBag = DisposeBag()

// 创建 Observable
let stringObservable = Observable.just("Hello RxSwift!")
let numbersObservable = Observable.of(1, 2, 3)

// 订阅事件
stringObservable
    .subscribe(
        onNext: { print($0) },
        onError: { print("Error: \($0)") },
        onCompleted: { print("Completed") }
    )
    .disposed(by: disposeBag)

/* 输出:
Hello RxSwift!
Completed
*/

3.2、操作符链式调用

swift 复制代码
Observable.of(1, 2, 3, 4, 5)
    .filter { $0 % 2 == 0 }      // 过滤偶数
    .map { $0 * 10 }             // 乘以10
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

/* 输出:
20
40
*/

3.3、绑定 UI 控件 (RxCocoa)

swift 复制代码
import RxSwift
import RxCocoa

class ViewController: UIViewController {
    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var label: UILabel!
    
    let disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 实时显示文本框内容(忽略空值)
        textField.rx.text
            .compactMap { $0 }  // 解包非空值
            .filter { !$0.isEmpty }
            .bind(to: label.rx.text)
            .disposed(by: disposeBag)
    }
}

3.4、网络请求 + 线程切换

swift 复制代码
func fetchUser() -> Observable<User> {
    return Observable.create { observer in
        let task = URLSession.shared.dataTask(with: URL(string: "https://api.example.com/user")!) { data, _, error in
            if let error = error {
                observer.onError(error)
            } else if let data = data {
                let user = try? JSONDecoder().decode(User.self, from: data)
                observer.onNext(user!)
                observer.onCompleted()
            }
        }
        task.resume()
        return Disposables.create { task.cancel() }
    }
}

// 使用示例
fetchUser()
    .subscribe(on: ConcurrentDispatchQueueScheduler(qos: .background)) // 后台线程请求
    .observe(on: MainScheduler.instance) // 主线程更新UI
    .subscribe(
        onNext: { user in
            print("用户名: \(user.name)")
        },
        onError: { print("请求失败: \($0)") }
    )
    .disposed(by: disposeBag)
3.5、组合多个请求 (flatMapLatest)
swift 复制代码
// 先登录 → 再获取用户信息
func login(username: String, password: String) -> Observable<String> {
    // 返回token的Observable
}

func fetchProfile(token: String) -> Observable<UserProfile> {
    // 使用token获取用户信息
}

login(username: "user", password: "pass")
    .flatMapLatest { token in
        fetchProfile(token: token) // 使用token获取用户信息
    }
    .subscribe(onNext: { profile in
        print("用户邮箱: \(profile.email)")
    })
    .disposed(by: disposeBag)

核心操作符速查

操作符 作用
map 数据转换
filter 条件过滤
flatMap 扁平化嵌套Observable
debounce 防抖动(搜索框场景)
combineLatest 合并最新值
merge 合并多个流
retry 失败自动重试

四、安装方式

Podfile 中添加:

ruby 复制代码
pod 'RxSwift', '~> 6.5'
pod 'RxCocoa', '~> 6.5'  # UI扩展

或使用 Swift Package Manager

swift 复制代码
dependencies: [
    .package(url: "https://github.com/ReactiveX/RxSwift.git", .upToNextMajor(from: "6.0.0"))
]

五、适用场景

  1. 实时搜索(debounce + flatMapLatest
  2. 表单验证(combineLatest 多个输入)
  3. 复杂异步依赖操作
  4. 多数据源绑定同一UI
  5. 状态管理(替代部分Delegate模式)

提示:RxSwift 学习曲线较陡,建议从简单场景逐步实践,配合 RxMarbles 可视化工具理解操作符行为。

相关推荐
终端安全笔记4 小时前
描述文件、企业证书、MDM 不是三个名字,是三层
android·ios·智能手机
传奇开心果编程4 小时前
【SwiftUI入门练中学】第1课 从零开始
学习·ui·ios·swiftui·swift
丿Wayne10 小时前
iOS Token 刷新实战(Actor 避免并发重复刷新)
ios·swift·token·actor·swift并发
终端安全笔记1 天前
iOS 27 给了租赁一个新工具,但它只认受监督的设备
android·网络·安全·ios
大熊猫侯佩1 天前
独立 App 首发完成 iPhone Duo 展开态适配
ios·swiftui·swift
光影少年1 天前
setImmediate 和 setTimeout(0) 的区别
android·前端·react.js·ios·前端框架
2501_916008891 天前
SSE 和 gRPC 流式接口如何抓包,调试 SSE 与 gRPC 流式接口
网络协议·计算机网络·网络安全·ios·adb·https·udp
HouWan2 天前
Flutter: MediaQuery.of(context) 为什么可能拖慢页面?
android·flutter·ios
SoaringHeart2 天前
Swift 进阶&封装:仿 Get 给SwiftUI 添加路由导航能力
swiftui·swift
用户38034165882972 天前
Broadcast Extension 里的 Live Activity:一次跨进程妥协
ios·音视频开发