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 单次结果 网络请求
相关推荐
游戏开发爱好者85 小时前
没有 Mac,如何上架 iOS App?多项目复用与流程标准化实战分享
android·ios·小程序·https·uni-app·iphone·webview
Digitally10 小时前
如何将 iPhone 备份到 Mac/MacBook
macos·ios·iphone
songgeb1 天前
Concurrency in Swift学习笔记-初识
ios·swift
mobsmobs1 天前
Flutter开发环境搭建与工具链
android·flutter·ios·android studio·xcode
SY.ZHOU1 天前
iOS上使用WebRTC推拉流的案例
ios·音视频·cocoa·webrtc
杂雾无尘1 天前
2025 年了,是否该全面拥抱 Swift 6?
ios·swift·客户端
Digitally1 天前
设置后轻松将 iPhone 转移到 iPhone
ios·iphone
2501_916007471 天前
iOS 抓包工具有哪些?2025实用指南与场景推荐
android·ios·小程序·https·uni-app·iphone·webview
ii_best1 天前
[iOS开发工具] 【iOS14以及以下】cydia商店按键精灵iOS新版V2.X安装教程
ios
KanS11 天前
2025真实面试试题分析-iOS客户端开发
ios·面试·职场和发展