什么是 Combine

Combine 是苹果的响应式编程框架,把"事件流"抽象成可组合的管道:数据从发布者流出,经过一系列操作符变换,到达订阅者。网络、通知、UI 事件都能统一成一条流。

Combine 让异步事件像流水线一样可编排。

和回调、代理相比,Combine 的管线更清晰:map 改数据、filter 过滤、combineLatest 合并多个流,链式写完一遍读下来就是业务逻辑本身。这篇从协议讲起,带你走完一条完整的响应式链路。

Publisher 与 Subscriber

Publisher 定义事件怎么发出,Subscriber 定义怎么接收。中间由订阅关系连接,订阅取消时整个管线停止。Just、Future 是最常用的两个 Publisher。

import Combine

let publisher = Just(42)
let cancel = publisher
  .map { $0 * 2 }
  .sink { value in
    print("收到", value) // 收到 84
  }
Combine 基础
  • Publisher产出值或错误。
  • Subscriber接收值并处理。
  • Cancelable取消订阅的令牌。

sink 返回 AnyCancellable,要存起来(比如存到属性里),否则订阅会立刻被释放,流就断了。这是 Combine 新手最常见的坑。

常用操作符

操作符是 Combine 的积木:map 变换值、filter 过滤、drop 跳过、merge 合并多流、combineLatest 取多流最新值、flatMap 展开嵌套流。

let numbers = [1, 2, 3, 4, 5].publisher
numbers
  .filter { $0 % 2 == 0 }
  .map { "偶数: \($0)" }
  .sink { print($0) } // 偶数: 2 偶数: 4
Combine:多条发光数据流从多个发布者圆形节点汇入一条主数据管道、末端连接方形订阅者节点的蓝调插画
多个发布者汇入一条数据管道。

操作符链别写太长,超过六个就拆成小函数,不然调试定位麻烦。每个操作符都可能改变输出类型,链的类型跟着变,编译期就能发现大部分错误。

Subjects 与状态管理

Subject 是"既当发布者又能手动发送值"的特殊角色:PassthroughSubject 只转发新值,CurrentValueSubject 保存当前值并转发给新订阅者。

let subject = CurrentValueSubject<Int, Never>(0)
subject.send(1)
subject.send(2)
let sub = subject.sink { print($0) } // 立刻收到 2

CurrentValueSubject 适合做可变状态:订阅即得现值,改了就推送,天然是状态管理的底座。注意别在多个地方 send 同一 subject,状态来源混乱是响应式项目的头号腐化源。