侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

使用Combine框架实现简单字符串发布与订阅

2025-12-12 / 0 评论 / 4 阅读

题目

使用Combine框架实现简单字符串发布与订阅

信息

  • 类型:问答
  • 难度:⭐

考点

Publisher创建,Subscriber订阅,Sink操作符

快速回答

使用Just创建Publisher,通过sink实现订阅:

  1. 创建字符串Publisher:let publisher = Just("Hello, Combine!")
  2. 使用sink订阅:publisher.sink { print($0) }
  3. 处理完成事件:在sinkreceiveCompletion中处理结束状态
## 解析

原理说明

Combine是Apple的响应式编程框架,核心是Publisher(发布者)和Subscriber(订阅者)模式:

  • Publisher:数据源,遵循Publisher协议,可发送值和完成事件
  • Subscriber:通过subscribe(_:)连接Publisher,接收数据流
  • Sink:最常用的订阅操作符,提供闭包处理数据和完成事件

代码示例

import Combine

// 1. 创建Publisher
let greetingPublisher = Just("Hello, Combine!")

// 2. 使用sink订阅
let cancellable = greetingPublisher.sink(
    receiveCompletion: { completion in
        switch completion {
        case .finished:
            print("数据流完成")
        case .failure(let error):
            print("错误: ", error) // Just不会发送错误
        }
    },
    receiveValue: { value in
        print("收到值: ", value) // 输出: Hello, Combine!
    }
)

// 3. 管理生命周期(可选)
// cancellable.cancel() // 需要时取消订阅

最佳实践

  • 使用Just发布单个值,适用于简单场景
  • 始终存储返回的AnyCancellable对象,否则订阅会立即被释放
  • receiveCompletion中处理完成/错误状态
  • 对于UI操作,在主线程接收数据:添加.receive(on: DispatchQueue.main)

常见错误

  • 忘记存储cancellable:导致订阅立即终止
    // 错误:未存储返回值
    Just("Hi").sink { print($0) } // 不会执行
  • 混淆Publisher类型Just只能发送一次值,PassthroughSubject适合多次发送
  • 线程问题:在后台线程更新UI
    publisher
        .subscribe(on: DispatchQueue.global()) // 在后台处理
        .receive(on: DispatchQueue.main)       // 在主线程接收(正确做法)
        .sink { ... }

扩展知识

  • Publisher类型
    • Just:发送单个值后结束
    • Future:异步返回单个值
    • PassthroughSubject:手动发送值的Publisher
  • 生命周期管理
    • AnyCancellable存储在Set<AnyCancellable>
    • 使用store(in: &cancellables)简化管理
  • 操作符链式调用
    ["A", "B", "C"].publisher
        .filter { $0 != "B" }
        .sink { print($0) } // 输出A,C