RxSwift实战:从传统开发到响应式编程的代码示例

这是一个RxSwift基本使用文章,具体的代码可以下载这个工程进行查看。RxSwiftLearn,示例代码来源于官方文档,自己只是在上边的学习项目中完善了一下代码,也可以直接去官网学习RxSwift中文文档

为什么选择RxSwift?

  1. 统一异步模型 :用Observable替代回调地狱
  2. 线程安全 :通过Scheduler明确线程调度
  3. 组合能力zip, flatMap等操作符灵活组合任务
  4. 生命周期管理DisposeBag自动清理资源
  5. 错误处理catchError, retry优雅处理异常

1. 按钮点击事件处理

✅ 传统实现(Target-Action)

swift 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    
    let btn = UIButton(type: .system)
    btn.setTitle("传统点击", for: .normal)
    btn.frame = CGRect(x: 50, y: 100, width: 120, height: 40)
    view.addSubview(btn)
    
    btn.addTarget(self, action: #selector(handleTap), for: .touchUpInside)
}

@objc func handleTap() {
    print("传统方式点击")
}

RxSwift实现

swift 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    
    let rxBtn = UIButton(type: .system)
    rxBtn.setTitle("Rx点击", for: .normal)
    rxBtn.backgroundColor = .systemBlue
    rxBtn.frame = CGRect(x: 50, y: 200, width: 120, height: 40)
    view.addSubview(rxBtn)
    
    rxBtn.rx.tap
        .subscribe(onNext: { [weak self] in
            print("响应式点击")
        })
        .disposed(by: disposeBag)
}

核心类解析

类名 作用 使用场景
rx.tap 扩展UIButton的点击事件流 替代addTarget
subscribe 订阅事件 处理点击逻辑
DisposeBag 管理资源释放 防止内存泄漏

2. 滚动视图事件监听

✅ 传统实现(UIScrollViewDelegate)

swift 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    
    let scrollView = UIScrollView()
    scrollView.frame = CGRect(x: 0, y: 300, width: 300, height: 200)
    scrollView.contentSize = CGSize(width: 300, height: 400)
    view.addSubview(scrollView)
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    print("传统滚动位置: $scrollView.contentOffset.x)")
}

✅ RxSwift实现

swift 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    
    let scrollView = UIScrollView()
    scrollView.frame = CGRect(x: 0, y: 300, width: 300, height: 200)
    scrollView.contentSize = CGSize(width: 300, height: 400)
    view.addSubview(scrollView)
    
    scrollView.rx.contentOffset
        .subscribe(onNext: { offset in
            print("响应式滚动位置: $offset.x)")
        })
        .disposed(by: disposeBag)
}

🔍 核心类解析

类名 作用 使用场景
rx.contentOffset 扩展UIScrollView的滚动事件流 替代scrollViewDidScroll
BehaviorSubject 保存最新偏移量 实时获取滚动位置

3. 网络请求链式调用

✅ 传统实现(回调嵌套)

swift 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    
    API.getToken { token in
        API.getUserInfo(token: token) { user in
            print("获取用户信息成功: $user.name)")
        } failure: { error in
            print("失败: $error)")
        }
    } failure: { error in
        print("失败: $error)")
    }
}

✅ RxSwift实现

swift 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    
    API.rx.getToken(username: "user", password: "123")
        .flatMapLatest { token in
            API.rx.getUserInfo(token: token)
        }
        .subscribe(
            onNext: { user in
                print("响应式获取用户: $user.name)")
            },
            onError: { error in
                print("响应式错误: $error)")
            }
        )
        .disposed(by: disposeBag)
}

核心类解析

类名 作用 使用场景
flatMapLatest 扁平化嵌套请求 实现请求链式调用
Single 单次结果封装 适配网络请求场景

4. 并发任务聚合

✅ 传统实现(串行请求)

swift 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    
    API.getTeacher(id: 1001) { teacher in
        API.getComments(id: 1001) { comments in
            print("教师: $teacher.name),评论数: $comments.count)")
        }
    }
}

✅ RxSwift实现

swift 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    
    Observable.zip(
        API.rx.getTeacher(id: 1001),
        API.rx.getComments(id: 1001)
    )
        .subscribe(
            onNext: { teacher, comments in
                print("教师: $teacher.name),评论数: $comments.count)")
            }
        )
        .disposed(by: disposeBag)
}

🔍 核心类解析

类名 作用 使用场景
zip 合并多个Observable 并发请求聚合
Tuple 存储组合结果 (Teacher, [Comment])类型

5. 冷热Observable对比

✅ 冷Observable(独立执行)

swift 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    
    let cold = Observable<Int>.create { observer in
        observer.onNext(1)
        return Disposables.create()
    }
    cold.subscribe { value in
        print("冷Observable: $value)")
    }
}

✅ 热Observable(共享事件)

swift 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    
    let hot = PublishSubject<Int>()
    hot.onNext(2)
    hot.subscribe { value in
        print("热Observable: $value)")
    }
}

🔍 核心类解析

类型 特点 使用场景
冷Observable 每次订阅独立执行 网络请求、一次性任务
热Observable 共享事件流 实时数据推送

6. 错误处理与重试机制

✅ RxSwift实现

swift 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    
    API.rx.login()
        .retry(3) // 最多重试3次
        .catchError { error in
            print("最终错误: $error)")
            return .just(User.default)
        }
        .subscribe { user in
            print("登录用户: $user.name)")
        }
        .disposed(by: disposeBag)
}

🔍 核心类解析

类名 作用 使用场景
retry 自动重试 网络不稳定时
catchError 错误降级 返回默认值避免崩溃

7. UI状态管理

✅ 传统实现(直接赋值)

swift 复制代码
var isLoading = false {
    didSet {
        activityIndicator.isHidden = !isLoading
    }
}

✅ RxSwift实现

swift 复制代码
let loadingState = BehaviorRelay<Bool>(value: false)
loadingState.asObservable()
    .subscribe { isLoad in
        activityIndicator.isHidden = !isLoad
    }
    .disposed(by: disposeBag)

🔍 核心类解析

类名 作用 使用场景
BehaviorRelay 可变状态容器 管理加载状态
asObservable() 转换为只读流 防止外部直接修改

所有核心类汇总表

类名 核心作用 典型使用场景
Observable 异步事件流 网络请求、用户交互
Observer 事件消费者 处理next/error/complete
Disposable 资源管理 取消订阅
Scheduler 线程调度 主线程更新
Operator 操作符 map, filter, zip
Subject 热Observable 实时事件广播
Relay 状态管理 BehaviorRelay, PublishRelay
Driver 安全绑定 UI绑定
Single 单次结果 网络请求
相关推荐
Sim14805 小时前
iPhone将内置本地大模型,手机端AI实现0 token成本时代来临?
人工智能·ios·智能手机·iphone
Digitally7 小时前
如何将 iPad 上的照片传输到 U 盘(4 种解决方案)
ios·ipad
报错小能手10 小时前
ios开发方向——swift并发进阶核心 @MainActor 与 DispatchQueue.main 解析
开发语言·ios·swift
LcGero10 小时前
Cocos Creator 业务与原生通信详解
android·ios·cocos creator·游戏开发·jsb
ii_best10 小时前
lua语言开发脚本基础、mql命令库开发、安卓/ios基础开发教程,按键精灵新手工具
android·ios·自动化·编辑器
用户223586218201 天前
WebKit WebPage API 的引入尝试与自研实现
ios
啦啦啦!2 天前
ChatGPT和Gemini的接入和封装
人工智能·ios·chatgpt
报错小能手2 天前
ios开发方向——swift并发进阶核心 async/await 详解
开发语言·ios·swift
开心就好20252 天前
HTTPS超文本传输安全协议全面解析与工作原理
后端·ios
牛马1112 天前
Flutter iOS 权限配置完整指南(定位权限)
flutter·ios