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 单次结果 网络请求
相关推荐
未来侦察班2 小时前
一晃13年过去了,苹果的Airdrop依然很坚挺。
macos·ios·苹果vision pro
锐意无限8 小时前
Swift 扩展归纳--- UIView
开发语言·ios·swift
符哥20088 小时前
用Apollo + RxSwift + RxCocoa搭建一套网络请求框架
网络·ios·rxswift
文件夹__iOS13 小时前
AsyncStream 进阶实战:SwiftUI 全局消息流极简实现
ios·swiftui·swift
2501_9160088915 小时前
深入解析iOS机审4.3原理与混淆实战方法
android·java·开发语言·ios·小程序·uni-app·iphone
忆江南15 小时前
Flutter深度全解析
ios
山水域15 小时前
Swift 6 严格并发检查:@Sendable 与 Actor 隔离的深度解析
ios
楚轩努力变强16 小时前
iOS 自动化环境配置指南 (Appium + WebDriverAgent)
javascript·学习·macos·ios·appium·自动化
游戏开发爱好者82 天前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
黑码哥2 天前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder