03-研究优秀开源框架@响应式编程@iOS | ReactiveCocoa框架:从使用到源码解析

6 阅读13分钟

📋 目录


一、ReactiveCocoa框架使用详解

1. ReactiveCocoa框架概述

ReactiveCocoa(简称 RAC)是一个基于 ReactiveSwift 的响应式编程框架,用于处理异步事件流和状态管理。它是 GitHub 开源的项目,提供了声明式的 API 来处理时间序列数据。

1.1 什么是ReactiveCocoa

ReactiveCocoa 是一个函数式响应式编程(FRP)框架,允许你通过组合不同的操作符来处理异步事件序列。它提供了声明式的 API 来处理时间序列数据。

核心特点:

  • 函数式响应式编程:基于函数式编程和响应式编程的结合
  • 类型安全:充分利用 Swift 的类型系统
  • 状态管理:提供 Property 和 MutableProperty 管理状态
  • Action模式:提供 Action 处理用户交互
  • UIKit集成:深度集成 UIKit 控件

1.2 ReactiveCocoa vs RxSwift vs Combine

特性ReactiveCocoaRxSwiftCombine
平台iOS、macOS跨平台Apple 生态(iOS 13+)
语言SwiftSwiftSwift
官方支持❌ GitHub 开源❌ 第三方✅ Apple 官方
核心类型Signal、SignalProducerObservablePublisher
状态管理Property、MutablePropertyBehaviorSubject@Published
Action模式✅ Action
学习曲线陡峭陡峭中等
生态ReactiveSwift、ReactiveObjCRxCocoaSwiftUI

1.3 ReactiveCocoa生态系统

  • ReactiveSwift:核心框架,提供 Signal、SignalProducer 等
  • ReactiveCocoa:UIKit/AppKit 集成,提供控件绑定
  • ReactiveObjC:Objective-C 版本

1.4 安装方式

CocoaPods:

pod 'ReactiveSwift', '~> 7.0'
pod 'ReactiveCocoa', '~> 12.0'

SPM:

dependencies: [
    .package(url: "https://github.com/ReactiveCocoa/ReactiveSwift.git", from: "7.0.0"),
    .package(url: "https://github.com/ReactiveCocoa/ReactiveCocoa.git", from: "12.0.0")
]

1.5 编程思想(背后的范式与理念)

ReactiveCocoa 明确标榜函数式响应式编程(FRP),将函数式与响应式结合;理解其背后的编程思想,能更好地区分 Signal / SignalProducer、Property、Action 的适用场景。

(1)函数式响应式编程(FRP)

  • 核心:在「响应式」的事件流之上,用函数式的方式组合与变换——把「随时间发生的事件」视为可映射、可过滤、可合并的值,通过纯函数组合成新流,而不是在观察者闭包里写满副作用。
  • 在 RAC 中Signal / SignalProducer 表示事件流,mapfilterflatMap 等操作符对流做纯变换,observestart 才真正消费并产生副作用;流与副作用边界清晰。
  • 与「仅响应式」的对比:FRP 强调「流即数据」,用转换与组合表达业务逻辑,观察者只做「最后一步」的响应,便于测试和复用。

(2)声明式 vs 命令式

维度命令式(Imperative)声明式(Declarative)
关注点「怎么做」:显式顺序与分支「做什么」:描述数据/事件如何变换与约束
典型写法回调嵌套、状态变量、if-else链式操作符:map / filter / combineLatest
在 RAC 中手写「请求 → 回调里判断 → 再请求」signal.map(...).flatMap(...).observeValues(...) 描述整条流水线

声明式让「事件从哪来、如何变换、到哪去」一目了然,便于阅读和单元测试。

(3)函数式思想(组合与不可变)

  • 组合(Composition):每个操作符只做一件事,通过 .map().filter().flatMap(.latest) 等组合成完整逻辑;小能力组合成大能力,避免巨型闭包。
  • 不可变(Immutability):操作符不修改原 Signal/SignalProducer,而是返回新的;原流不变,便于复用和推理。
  • 副作用边界:纯变换放在操作符链中,副作用(UI 更新、写库、弹窗)集中在 observeValues / startWithValuesAction 的 execution 中,便于测试和并发安全。

(4)流与时间(Streams & Time)

  • 把所有「会随时间产生的事件」都视为时间序列:value、value、…、completed/failed/interrupted。
  • RAC 区分热信号(Signal)冷信号(SignalProducer):热信号有订阅即开始发送、多订阅者共享同一时间线;冷信号每次 start 才执行、每次订阅独立。时间相关操作符如 debouncethrottle 表达「何时」而不只是「何值」。

(5)观察者与「推」「拉」

  • 观察者模式:Observer 通过 observe 订阅 Signal,或通过 start 启动 SignalProducer,在事件发生时被通知。
  • 推模型:Signal 是「推」——事件由发送端推动,观察者被动接收;SignalProducer 是「按需拉」——只有 start 时才创建并执行,适合表示「一次异步操作」或「延迟计算」。

(6)Action 与「意图-执行」分离

  • 思想:用户操作(点击、下拉)是意图,网络请求、校验、弹窗是执行;将「意图」与「执行」分离,便于禁用、重试、统一错误处理。
  • 在 RAC 中Action 接收输入(如按钮 tap 或输入值),内部用 SignalProducer 描述一次执行,输出与错误统一由 Action 暴露;UI 只绑定「能否执行」与「执行结果」,不写一堆 isLoadingerror 状态。

小结:ReactiveCocoa 用声明式事件流(Signal/SignalProducer)和可组合操作符,在函数式响应式的范式下做异步与事件处理;用 Property 管理可变状态、用 Action 封装「意图-执行」,并用 Scheduler 控制线程。掌握这些思想后,再区分「用 Signal 还是 SignalProducer」「何时用 Property、何时用 Action」会更自然。


2. 核心概念

2.1 Signal(信号)

Signal 是 ReactiveCocoa 的核心类型,表示一个可以观察的事件流。

protocol SignalProtocol {
    associatedtype Value
    associatedtype Error: Swift.Error
    
    func observe(_ observer: Observer<Value, Error>) -> Disposable?
}

特点:

  • 可以发出零个或多个值
  • 可能以完成或错误结束
  • 是引用类型(class)
  • 热信号(Hot Signal):有订阅者时立即开始发送事件

事件类型:

enum Event<Value, Error: Swift.Error> {
    case value(Value)      // 值事件
    case failed(Error)    // 错误事件
    case completed        // 完成事件
    case interrupted      // 中断事件
}

示例:

let (signal, observer) = Signal<String, Never>.pipe()

signal.observeValues { value in
    print("收到值: \(value)")
}

observer.send(value: "Hello")
observer.send(value: "World")
observer.sendCompleted()

2.2 SignalProducer(信号生产者)

SignalProducer 是延迟创建 Signal 的类型,类似于 RxSwift 的 Observable。

struct SignalProducer<Value, Error: Swift.Error> {
    private let startHandler: (Observer<Value, Error>, Lifetime) -> Void
    
    func start(_ observer: Observer<Value, Error>) -> Disposable
}

特点:

  • 冷信号(Cold Signal):只有在被订阅时才开始发送事件
  • 每次订阅都会创建新的 Signal
  • 适合表示异步操作

示例:

let producer = SignalProducer<String, Never> { observer, lifetime in
    observer.send(value: "Hello")
    observer.send(value: "World")
    observer.sendCompleted()
}

producer.startWithValues { value in
    print("收到值: \(value)")
}

2.3 Observer(观察者)

Observer 是接收 Signal 事件的类型。

final class Observer<Value, Error: Swift.Error> {
    func send(value: Value)
    func send(error: Error)
    func sendCompleted()
    func sendInterrupted()
}

示例:

let (signal, observer) = Signal<Int, Never>.pipe()

signal.observe { event in
    switch event {
    case .value(let value):
        print("值: \(value)")
    case .completed:
        print("完成")
    case .failed(let error):
        print("错误: \(error)")
    case .interrupted:
        print("中断")
    }
}

observer.send(value: 1)
observer.send(value: 2)
observer.sendCompleted()

2.4 Disposable(可释放资源)

Disposable 表示订阅关系,用于取消订阅和释放资源。

protocol Disposable {
    func dispose()
}

CompositeDisposable:

let disposable = CompositeDisposable()

disposable += signal.observeValues { value in
    print(value)
}

disposable += anotherSignal.observeValues { value in
    print(value)
}

// 释放所有订阅
disposable.dispose()

3. Signal与SignalProducer

3.1 Signal创建方式

pipe

创建 Signal 和 Observer。

let (signal, observer) = Signal<String, Never>.pipe()

signal.observeValues { print($0) }
observer.send(value: "Hello")
never

创建永不发出事件的 Signal。

let signal = Signal<Int, Never>.never()
signal.observeValues { print($0) }  // 永远不会执行
empty

创建立即完成的 Signal。

let signal = Signal<Int, Never>.empty()
signal.observeCompleted { print("完成") }
failed

创建立即失败的 Signal。

enum MyError: Error {
    case failure
}

let signal = Signal<Int, MyError>.failed(.failure)
signal.observeFailed { print("错误: \($0)") }

3.2 SignalProducer创建方式

init

使用闭包创建 SignalProducer。

let producer = SignalProducer<String, Never> { observer, lifetime in
    observer.send(value: "A")
    observer.send(value: "B")
    observer.sendCompleted()
}

producer.startWithValues { print($0) }
value

创建发出单个值的 SignalProducer。

let producer = SignalProducer<String, Never>(value: "Hello")
producer.startWithValues { print($0) }
values

从序列创建 SignalProducer。

let producer = SignalProducer<String, Never>(values: ["A", "B", "C"])
producer.startWithValues { print($0) }
error

创建立即失败的 SignalProducer。

let producer = SignalProducer<Int, MyError>(error: .failure)
producer.startWithFailed { print("错误: \($0)") }
empty

创建立即完成的 SignalProducer。

let producer = SignalProducer<Int, Never>.empty
producer.startWithCompleted { print("完成") }
never

创建永不发出事件的 SignalProducer。

let producer = SignalProducer<Int, Never>.never
producer.startWithValues { print($0) }  // 永远不会执行

3.3 Signal vs SignalProducer

Signal(热信号):

  • 立即开始发送事件
  • 多个观察者共享同一个事件流
  • 适合表示已经发生的事件

SignalProducer(冷信号):

  • 延迟创建,只有在订阅时才开始
  • 每个观察者获得独立的事件流
  • 适合表示异步操作

转换:

// SignalProducer -> Signal
let producer = SignalProducer<String, Never>(value: "Hello")
let signal = producer.promoteToSignal()

// Signal -> SignalProducer
let (signal, observer) = Signal<String, Never>.pipe()
let producer = SignalProducer(signal)

4. Property与MutableProperty

4.1 Property

Property 是不可变的状态容器,表示一个随时间变化的值。

protocol PropertyProtocol {
    associatedtype Value
    
    var value: Value { get }
    var signal: Signal<Value, Never> { get }
    var producer: SignalProducer<Value, Never> { get }
}

特点:

  • 只读属性
  • 提供当前值
  • 提供 Signal 和 SignalProducer 观察变化

示例:

let property = Property(value: "初始值")

// 获取当前值
print(property.value)  // 输出: 初始值

// 观察变化
property.signal.observeValues { value in
    print("值变化: \(value)")
}

4.2 MutableProperty

MutableProperty 是可变的状态容器。

final class MutableProperty<Value>: MutablePropertyProtocol {
    var value: Value { get set }
    var signal: Signal<Value, Never> { get }
    var producer: SignalProducer<Value, Never> { get }
    
    init(_ value: Value)
}

特点:

  • 可读写属性
  • 修改值时会发出事件
  • 新观察者会立即收到当前值

示例:

let property = MutableProperty("初始值")

// 观察变化
property.signal.observeValues { value in
    print("值变化: \(value)")
}
// 立即输出: 值变化: 初始值

// 修改值
property.value = "新值"  // 输出: 值变化: 新值
property.value = "另一个值"  // 输出: 值变化: 另一个值

4.3 Property绑定

双向绑定:

let property1 = MutableProperty("")
let property2 = MutableProperty("")

// 双向绑定
property1 <~ property2
property2 <~ property1

property1.value = "Hello"  // property2.value 也变为 "Hello"
property2.value = "World"  // property1.value 也变为 "World"

单向绑定:

let source = MutableProperty("源")
let target = MutableProperty("目标")

// 单向绑定:source -> target
target <~ source

source.value = "新值"  // target.value 也变为 "新值"
target.value = "修改"  // source.value 不变

5. Action

Action 是 ReactiveCocoa 特有的类型,用于处理用户交互和异步操作。

5.1 Action基本使用

let action = Action<String, String, Never> { input in
    return SignalProducer { observer, lifetime in
        // 执行异步操作
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            observer.send(value: "结果: \(input)")
            observer.sendCompleted()
        }
    }
}

// 执行 Action
action.apply("输入").startWithValues { result in
    print(result)  // 输出: 结果: 输入
}

5.2 Action状态

Action 提供多个状态 Signal:

let action = Action<String, String, Never> { input in
    return SignalProducer(value: "结果: \(input)")
}

// 观察执行状态
action.isExecuting.signal.observeValues { isExecuting in
    print("执行中: \(isExecuting)")
}

// 观察值
action.values.observeValues { value in
    print("值: \(value)")
}

// 观察错误
action.errors.observeValues { error in
    print("错误: \(error)")
}

// 执行
action.apply("输入").start()

5.3 Action与UIButton绑定

let action = Action<Void, String, Never> {
    return SignalProducer(value: "按钮点击")
}

// 绑定到按钮
button.reactive.pressed = CocoaAction(action) { _ in }

// 观察结果
action.values.observeValues { result in
    print(result)
}

6. Operators操作符

6.1 转换操作符

map

转换每个值。

SignalProducer(values: [1, 2, 3])
    .map { $0 * 2 }
    .startWithValues { print($0) }
// 输出: 2, 4, 6
flatMap

将 Signal 发出的值转换为 SignalProducer,然后合并。

SignalProducer(values: ["A", "B", "C"])
    .flatMap(.latest) { letter in
        SignalProducer(values: [1, 2]).map { "\(letter)\($0)" }
    }
    .startWithValues { print($0) }
// 输出: A1, A2, B1, B2, C1, C2
scan

累积值。

SignalProducer(values: [1, 2, 3, 4, 5])
    .scan(0, +)
    .startWithValues { print($0) }
// 输出: 1, 3, 6, 10, 15

6.2 过滤操作符

filter

过滤值。

SignalProducer(values: [1, 2, 3, 4, 5])
    .filter { $0 % 2 == 0 }
    .startWithValues { print($0) }
// 输出: 2, 4
skip

跳过前几个值。

SignalProducer(values: [1, 2, 3, 4, 5])
    .skip(first: 2)
    .startWithValues { print($0) }
// 输出: 3, 4, 5
take

获取前几个值。

SignalProducer(values: [1, 2, 3, 4, 5])
    .take(first: 3)
    .startWithValues { print($0) }
// 输出: 1, 2, 3
distinctUntilChanged

移除连续重复的值。

SignalProducer(values: [1, 1, 2, 2, 3, 3])
    .distinctUntilChanged()
    .startWithValues { print($0) }
// 输出: 1, 2, 3

6.3 组合操作符

combineLatest

组合多个 Signal 的最新值。

let (signal1, observer1) = Signal<String, Never>.pipe()
let (signal2, observer2) = Signal<Int, Never>.pipe()

signal1.combineLatest(with: signal2)
    .observeValues { value1, value2 in
        print("\(value1): \(value2)")
    }

observer1.send(value: "A")  // 无输出(等待 signal2)
observer2.send(value: 1)    // 输出: A: 1
observer1.send(value: "B")  // 输出: B: 1
observer2.send(value: 2)    // 输出: B: 2
merge

合并多个 Signal。

let (signal1, observer1) = Signal<Int, Never>.pipe()
let (signal2, observer2) = Signal<Int, Never>.pipe()

signal1.merge(with: signal2)
    .observeValues { print($0) }

observer1.send(value: 1)  // 输出: 1
observer2.send(value: 2)  // 输出: 2
observer1.send(value: 3)  // 输出: 3
zip

按顺序组合多个 Signal。

let (signal1, observer1) = Signal<String, Never>.pipe()
let (signal2, observer2) = Signal<Int, Never>.pipe()

signal1.zip(with: signal2)
    .observeValues { value1, value2 in
        print("\(value1): \(value2)")
    }

observer1.send(value: "A")  // 等待 signal2
observer1.send(value: "B")  // 等待 signal2
observer2.send(value: 1)    // 输出: A: 1
observer2.send(value: 2)    // 输出: B: 2

6.4 时间操作符

debounce

防抖,等待指定时间后发出最新值。

let (signal, observer) = Signal<String, Never>.pipe()

signal.debounce(0.5, on: QueueScheduler.main)
    .observeValues { print($0) }

observer.send(value: "H")     // 不输出
observer.send(value: "He")    // 不输出
observer.send(value: "Hel")   // 不输出
observer.send(value: "Hell")  // 不输出
observer.send(value: "Hello") // 0.5秒后输出: Hello
throttle

节流,在指定时间间隔内只发出第一个值。

let (signal, observer) = Signal<String, Never>.pipe()

signal.throttle(1.0, on: QueueScheduler.main)
    .observeValues { print($0) }

observer.send(value: "A")  // 立即输出: A
observer.send(value: "B")  // 不输出(1秒内)
observer.send(value: "C")  // 不输出(1秒内)
// 1秒后
observer.send(value: "D")  // 输出: D
delay

延迟发出值。

SignalProducer(values: [1, 2, 3])
    .delay(1.0, on: QueueScheduler.main)
    .startWithValues { print($0) }
// 1秒后依次输出: 1, 2, 3

7. Schedulers调度器

7.1 内置Scheduler

QueueScheduler

队列调度器。

// 主队列
let mainScheduler = QueueScheduler.main

// 后台队列
let backgroundScheduler = QueueScheduler(
    qos: .background,
    name: "background.queue"
)

SignalProducer(value: 1)
    .start(on: backgroundScheduler)
    .observe(on: mainScheduler)
    .startWithValues { value in
        print(Thread.isMainThread)  // true
    }
UIScheduler

UI 调度器(主线程)。

let uiScheduler = UIScheduler()

SignalProducer(value: 1)
    .observe(on: uiScheduler)
    .startWithValues { value in
        print(Thread.isMainThread)  // true
    }

7.2 start vs observe

  • start:指定 SignalProducer 在哪个调度器上开始执行
  • observe:指定观察者在哪个调度器上接收事件
SignalProducer { observer, lifetime in
    print("执行线程: \(Thread.current)")
    observer.send(value: 1)
    observer.sendCompleted())
}
.start(on: QueueScheduler(qos: .background))
.observe(on: UIScheduler())
.startWithValues { value in
    print("接收线程: \(Thread.current)")
}

8. 错误处理

8.1 错误类型

enum NetworkError: Error {
    case invalidURL
    case noData
    case decodingError
}

8.2 错误处理操作符

catch

捕获错误并返回备用 SignalProducer。

SignalProducer<String, NetworkError>(error: .noData)
    .catch { error -> SignalProducer<String, Never> in
        print("捕获错误: \(error)")
        return SignalProducer(value: "备用值")
    }
    .startWithValues { print($0) }
retry

重试失败的 SignalProducer。

var attempts = 0

SignalProducer<String, NetworkError> { observer, lifetime in
    attempts += 1
    if attempts < 3 {
        observer.send(error: .noData)
    } else {
        observer.send(value: "成功")
        observer.sendCompleted()
    }
}
.retry(upTo: 2)  // 最多重试 2 次
.start(
    value: { print($0) },
    failed: { print("错误: \($0)") }
)
flatMapError

将错误转换为值。

SignalProducer<String, NetworkError>(error: .noData)
    .flatMapError { error in
        SignalProducer(value: "错误: \(error)")
    }
    .startWithValues { print($0) }

9. 内存管理

9.1 Lifetime

Lifetime 用于管理 SignalProducer 的生命周期。

let producer = SignalProducer<String, Never> { observer, lifetime in
    let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
        observer.send(value: "Tick")
    }
    
    lifetime.observeEnded {
        timer.invalidate()
    }
}

let disposable = producer.startWithValues { print($0) }

// 取消订阅时,timer 会自动失效
disposable.dispose()

9.2 避免循环引用

class ViewModel {
    private let property = MutableProperty("")
    
    func setup() {
        property.signal.observeValues { [weak self] value in
            self?.process(value)
        }
    }
    
    private func process(_ value: String) {
        // 处理数据
    }
}

10. 与UIKit集成

10.1 Reactive扩展

ReactiveCocoa 为 UIKit 控件提供了 Reactive 扩展。

import ReactiveSwift
import ReactiveCocoa

class ViewController: UIViewController {
    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var button: UIButton!
    @IBOutlet weak var label: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 文本输入绑定
        label.reactive.text <~ textField.reactive.continuousTextValues
        
        // 按钮点击
        button.reactive.pressed = CocoaAction(Action { [weak self] _ in
            return SignalProducer(value: "按钮点击")
        })
    }
}

10.2 常用绑定

// UILabel
label.reactive.text <~ property.producer.map { $0 }

// UITextField
textField.reactive.text <~ property.producer.map { $0 }
property <~ textField.reactive.continuousTextValues

// UIButton
button.reactive.pressed = CocoaAction(action)

// UISwitch
switch.reactive.isOn <~ property.producer.map { $0 }
property <~ switch.reactive.isOnValues

// UISlider
slider.reactive.value <~ property.producer.map { Float($0) }
property <~ slider.reactive.values.map { Int($0) }

11. 实际应用场景

11.1 网络请求

struct API {
    static func fetchUser(id: Int) -> SignalProducer<User, NetworkError> {
        let url = URL(string: "https://api.example.com/users/\(id)")!
        
        return URLSession.shared.reactive.data(with: URLRequest(url: url))
            .attemptMap { data, _ in
                try JSONDecoder().decode(User.self, from: data)
            }
            .observe(on: UIScheduler())
    }
}

API.fetchUser(id: 1)
    .start(
        value: { user in
            print("用户: \(user)")
        },
        failed: { error in
            print("错误: \(error)")
        }
    )

11.2 用户输入处理

class SearchViewModel {
    let searchText = MutableProperty("")
    let results = MutableProperty<[String]>([])
    
    init() {
        results <~ searchText.producer
            .debounce(0.5, on: QueueScheduler.main)
            .skipRepeats()
            .filter { !$0.isEmpty }
            .flatMap(.latest) { query -> SignalProducer<[String], Never> in
                return self.search(query: query)
                    .flatMapError { _ in SignalProducer(value: []) }
            }
    }
    
    private func search(query: String) -> SignalProducer<[String], NetworkError> {
        // 实现搜索逻辑
        return SignalProducer(value: ["结果1", "结果2"])
    }
}

二、ReactiveCocoa框架源码解析

1. 架构设计

1.1 整体架构

ReactiveCocoa 采用协议导向的设计,核心是 Signal 和 SignalProducer。

Signal (热信号)
    ↓
Observer
    ↓
Event (value/failed/completed/interrupted)

SignalProducer (冷信号)
    ↓
Observer
    ↓
Signal

1.2 核心协议层次

// Signal 协议
protocol SignalProtocol {
    associatedtype Value
    associatedtype Error: Swift.Error
    
    func observe(_ observer: Observer<Value, Error>) -> Disposable?
}

// SignalProducer 协议
protocol SignalProducerProtocol {
    associatedtype Value
    associatedtype Error: Swift.Error
    
    func start(_ observer: Observer<Value, Error>) -> Disposable
}

2. Signal实现原理

2.1 Signal类实现

public final class Signal<Value, Error: Swift.Error>: SignalProtocol {
    private let generator: (Observer<Value, Error>) -> Disposable?
    private var observers: Bag<Observer<Value, Error>> = Bag()
    private let lock = NSRecursiveLock()
    
    public init(_ generator: @escaping (Observer<Value, Error>) -> Disposable?) {
        self.generator = generator
    }
    
    public func observe(_ observer: Observer<Value, Error>) -> Disposable? {
        lock.lock()
        defer { lock.unlock() }
        
        let token = observers.insert(observer)
        
        // 如果是第一个观察者,开始生成事件
        if observers.count == 1 {
            let disposable = generator(Observer { [weak self] event in
                self?.send(event)
            })
            
            return CompositeDisposable(
                disposable,
                Disposable { [weak self] in
                    self?.lock.lock()
                    self?.observers.remove(using: token)
                    self?.lock.unlock()
                }
            )
        }
        
        return Disposable { [weak self] in
            self?.lock.lock()
            self?.observers.remove(using: token)
            self?.lock.unlock()
        }
    }
    
    private func send(_ event: Event<Value, Error>) {
        lock.lock()
        let currentObservers = observers
        lock.unlock()
        
        for observer in currentObservers {
            observer.send(event)
        }
        
        // 如果是终止事件,清理观察者
        if event.isTerminating {
            lock.lock()
            observers.removeAll()
            lock.unlock()
        }
    }
}

关键点:

  • Signal 是引用类型(class)
  • 使用 Bag 存储多个观察者
  • 使用锁保护共享状态
  • 第一个观察者订阅时开始生成事件

2.2 pipe实现

extension Signal {
    public static func pipe() -> (Signal<Value, Error>, Observer<Value, Error>) {
        let observer = Observer<Value, Error>()
        let signal = Signal<Value, Error> { observer in
            // 将外部 observer 的事件转发给内部 observer
            return observer.observe { event in
                observer.send(event)
            }
        }
        
        return (signal, observer)
    }
}

关键点:

  • pipe 创建 Signal 和 Observer 对
  • Observer 可以手动发送事件
  • 适合将命令式代码转换为响应式代码

3. SignalProducer实现原理

3.1 SignalProducer结构

public struct SignalProducer<Value, Error: Swift.Error>: SignalProducerProtocol {
    private let startHandler: (Observer<Value, Error>, Lifetime) -> Void
    
    public init(_ startHandler: @escaping (Observer<Value, Error>, Lifetime) -> Void) {
        self.startHandler = startHandler
    }
    
    public func start(_ observer: Observer<Value, Error>) -> Disposable {
        let lifetime = Lifetime()
        let compositeDisposable = CompositeDisposable()
        
        lifetime.observeEnded {
            compositeDisposable.dispose()
        }
        
        startHandler(observer, lifetime)
        
        return compositeDisposable
    }
}

关键点:

  • SignalProducer 是值类型(struct)
  • 每次 start 都会创建新的 Signal
  • 使用 Lifetime 管理资源生命周期

3.2 SignalProducer转换

extension SignalProducer {
    public var signal: Signal<Value, Error> {
        return Signal { observer in
            return self.start(observer)
        }
    }
}

extension Signal {
    public var producer: SignalProducer<Value, Error> {
        return SignalProducer { observer, lifetime in
            let disposable = self.observe(observer)
            lifetime.observeEnded {
                disposable?.dispose()
            }
        }
    }
}

关键点:

  • SignalProducer 可以转换为 Signal
  • Signal 可以转换为 SignalProducer
  • 转换是延迟的,不会立即执行

4. Property实现原理

4.1 Property协议

public protocol PropertyProtocol {
    associatedtype Value
    
    var value: Value { get }
    var signal: Signal<Value, Never> { get }
    var producer: SignalProducer<Value, Never> { get }
}

4.2 MutableProperty实现

public final class MutableProperty<Value>: MutablePropertyProtocol {
    private let lock = NSRecursiveLock()
    private var _value: Value
    private let observer: Observer<Value, Never>
    private let signal: Signal<Value, Never>
    
    public var value: Value {
        get {
            lock.lock()
            defer { lock.unlock() }
            return _value
        }
        set {
            lock.lock()
            let oldValue = _value
            _value = newValue
            lock.unlock()
            
            if oldValue != newValue {
                observer.send(value: newValue)
            }
        }
    }
    
    public init(_ value: Value) {
        _value = value
        let (signal, observer) = Signal<Value, Never>.pipe()
        self.signal = signal
        self.observer = observer
        
        // 立即发送初始值
        observer.send(value: value)
    }
    
    public var producer: SignalProducer<Value, Never> {
        return SignalProducer { observer, lifetime in
            // 立即发送当前值
            observer.send(value: self.value)
            
            // 观察后续变化
            let disposable = self.signal.observe(observer)
            lifetime.observeEnded {
                disposable?.dispose()
            }
        }
    }
}

关键点:

  • MutableProperty 是引用类型
  • 使用锁保护 _value
  • 值变化时发出事件
  • producer 会立即发送当前值

4.3 绑定操作符实现

infix operator <~ : BindingPrecedence

public func <~ <Source: SignalProducerProtocol, Destination: BindingTargetProtocol>(
    destination: Destination,
    source: Source
) -> Disposable
where Source.Value == Destination.Value, Source.Error == Never {
    return source.startWithValues { value in
        destination.consume(value)
    }
}

public func <~ <Source: SignalProtocol, Destination: BindingTargetProtocol>(
    destination: Destination,
    source: Source
) -> Disposable?
where Source.Value == Destination.Value, Source.Error == Never {
    return source.observeValues { value in
        destination.consume(value)
    }
}

关键点:

  • <~ 操作符实现单向绑定
  • 自动管理订阅生命周期
  • 支持 Signal 和 SignalProducer

5. Action实现原理

5.1 Action结构

public final class Action<Input, Output, Error: Swift.Error> {
    private let executeClosure: (Input) -> SignalProducer<Output, Error>
    private let isEnabledProperty: MutableProperty<Bool>
    private let eventsObserver: Observer<Event<Output, Error>, Never>
    
    public let isEnabled: Property<Bool>
    public let isExecuting: Property<Bool>
    public let values: Signal<Output, Never>
    public let errors: Signal<Error, Never>
    public let events: Signal<Event<Output, Error>, Never>
    
    public init(enabledIf: Property<Bool> = Property(value: true),
                execute: @escaping (Input) -> SignalProducer<Output, Error>) {
        self.executeClosure = execute
        self.isEnabledProperty = MutableProperty(true)
        self.isEnabled = Property(capturing: isEnabledProperty)
        
        let (eventsSignal, eventsObserver) = Signal<Event<Output, Error>, Never>.pipe()
        self.events = eventsSignal
        self.eventsObserver = eventsObserver
        
        self.values = events.map { $0.value }.skipNil()
        self.errors = events.map { $0.error }.skipNil()
        
        let isExecutingProperty = MutableProperty(false)
        self.isExecuting = Property(capturing: isExecutingProperty)
        
        // 监听执行状态
        events.observeValues { event in
            switch event {
            case .value:
                isExecutingProperty.value = true
            case .completed, .failed, .interrupted:
                isExecutingProperty.value = false
            }
        }
    }
    
    public func apply(_ input: Input) -> SignalProducer<Output, Error> {
        return SignalProducer { observer, lifetime in
            guard self.isEnabled.value else {
                observer.sendInterrupted()
                return
            }
            
            let producer = self.executeClosure(input)
            let disposable = producer.start { event in
                self.eventsObserver.send(value: event)
                observer.send(event)
            }
            
            lifetime.observeEnded {
                disposable.dispose()
            }
        }
    }
}

关键点:

  • Action 封装异步操作
  • 提供执行状态(isEnabled、isExecuting)
  • 提供值、错误、事件流
  • 可以禁用 Action

6. Operators实现原理

6.1 map实现

extension SignalProducer {
    public func map<U>(_ transform: @escaping (Value) -> U) -> SignalProducer<U, Error> {
        return SignalProducer { observer, lifetime in
            self.start { event in
                switch event {
                case .value(let value):
                    observer.send(value: transform(value))
                case .failed(let error):
                    observer.send(error: error)
                case .completed:
                    observer.sendCompleted()
                case .interrupted:
                    observer.sendInterrupted()
                }
            }
        }
    }
}

关键点:

  • map 创建新的 SignalProducer
  • 转换每个值事件
  • 保持其他事件不变

6.2 filter实现

extension SignalProducer {
    public func filter(_ predicate: @escaping (Value) -> Bool) -> SignalProducer<Value, Error> {
        return SignalProducer { observer, lifetime in
            self.start { event in
                switch event {
                case .value(let value):
                    if predicate(value) {
                        observer.send(value: value)
                    }
                case .failed(let error):
                    observer.send(error: error)
                case .completed:
                    observer.sendCompleted()
                case .interrupted:
                    observer.sendInterrupted()
                }
            }
        }
    }
}

关键点:

  • filter 创建新的 SignalProducer
  • 只转发满足条件的值
  • 保持其他事件不变

6.3 flatMap实现

extension SignalProducer {
    public func flatMap<U>(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> SignalProducer<U, Error>) -> SignalProducer<U, Error> {
        return SignalProducer { observer, lifetime in
            let flattenProducer = self.map(transform).flatten(strategy)
            let disposable = flattenProducer.start(observer)
            lifetime.observeEnded {
                disposable.dispose()
            }
        }
    }
}

关键点:

  • flatMap 支持多种策略(.latest、.merge、.concat)
  • 管理多个内部 SignalProducer
  • 需要复杂的生命周期管理

7. Schedulers实现原理

7.1 Scheduler协议

public protocol Scheduler {
    func schedule(_ action: @escaping () -> Void) -> Disposable?
    func schedule(after date: Date, action: @escaping () -> Void) -> Disposable?
    func schedule(after date: Date, interval: TimeInterval, action: @escaping () -> Void) -> Disposable?
}

7.2 QueueScheduler实现

public final class QueueScheduler: Scheduler {
    public let queue: DispatchQueue
    
    public init(qos: DispatchQoS = .default, name: String = "org.reactivecocoa.ReactiveSwift.QueueScheduler") {
        self.queue = DispatchQueue(label: name, qos: qos)
    }
    
    public static let main = QueueScheduler(queue: .main, name: "org.reactivecocoa.ReactiveSwift.QueueScheduler.main")
    
    public func schedule(_ action: @escaping () -> Void) -> Disposable? {
        let disposable = SimpleDisposable()
        queue.async {
            if !disposable.isDisposed {
                action()
            }
        }
        return disposable
    }
    
    public func schedule(after date: Date, action: @escaping () -> Void) -> Disposable? {
        let disposable = SimpleDisposable()
        let timeInterval = date.timeIntervalSinceNow
        queue.asyncAfter(deadline: .now() + timeInterval) {
            if !disposable.isDisposed {
                action()
            }
        }
        return disposable
    }
}

关键点:

  • QueueScheduler 使用 DispatchQueue
  • 支持立即和延迟调度
  • 支持取消调度

8. 生命周期管理

8.1 Lifetime实现

public final class Lifetime {
    private let token: Token
    private var observers: Bag<() -> Void> = Bag()
    private let lock = NSRecursiveLock()
    
    public init() {
        token = Token()
    }
    
    public func observeEnded(_ action: @escaping () -> Void) {
        lock.lock()
        let isEnded = token.isEnded
        if !isEnded {
            observers.insert(action)
        }
        lock.unlock()
        
        if isEnded {
            action()
        }
    }
    
    deinit {
        token.markEnded()
        lock.lock()
        let currentObservers = observers
        observers.removeAll()
        lock.unlock()
        
        for observer in currentObservers {
            observer()
        }
    }
}

关键点:

  • Lifetime 管理资源生命周期
  • 对象释放时自动执行清理操作
  • 使用 observeEnded 注册清理回调

8.2 Disposable管理

public final class CompositeDisposable: Disposable {
    private var disposables: [Disposable] = []
    private let lock = NSRecursiveLock()
    private var isDisposed = false
    
    public init(_ disposables: Disposable...) {
        self.disposables = disposables
    }
    
    public func add(_ disposable: Disposable?) {
        guard let disposable = disposable else { return }
        
        lock.lock()
        if isDisposed {
            lock.unlock()
            disposable.dispose()
            return
        }
        
        disposables.append(disposable)
        lock.unlock()
    }
    
    public func dispose() {
        lock.lock()
        guard !isDisposed else {
            lock.unlock()
            return
        }
        
        isDisposed = true
        let currentDisposables = disposables
        disposables.removeAll()
        lock.unlock()
        
        for disposable in currentDisposables {
            disposable.dispose()
        }
    }
}

关键点:

  • CompositeDisposable 管理多个 Disposable
  • 线程安全
  • 一次性释放所有资源

9. 性能优化策略

9.1 值类型优化

SignalProducer 是值类型,避免堆分配:

// 值类型,零成本抽象
struct SignalProducer<Value, Error: Swift.Error> { }

9.2 延迟执行

SignalProducer 延迟创建 Signal:

let producer = SignalProducer<String, Never> { observer, lifetime in
    // 只在 start 时执行
    observer.send(value: "Hello")
}

9.3 共享执行

使用 share() 共享 SignalProducer:

let shared = expensiveProducer().share()

shared.startWithValues { }  // 订阅1
shared.startWithValues { }  // 订阅2(共享执行)

9.4 内存优化

  • 使用 weak 引用避免循环引用
  • 使用 Lifetime 自动管理资源
  • 及时释放不需要的订阅

📚 总结

ReactiveCocoa 的核心优势

  1. Property 状态管理:提供 Property 和 MutableProperty 管理状态
  2. Action 模式:提供 Action 处理用户交互和异步操作
  3. 类型安全:充分利用 Swift 类型系统
  4. 生命周期管理:使用 Lifetime 自动管理资源
  5. UIKit 集成:深度集成 UIKit 控件

学习建议

  1. 理解 Signal vs SignalProducer:掌握热信号和冷信号的区别
  2. 理解 Property:掌握状态管理
  3. 理解 Action:掌握用户交互处理
  4. 阅读源码:深入理解实现原理
  5. 实际应用:在项目中应用 ReactiveCocoa

文档版本:v1.0
最后更新:2026年1月15日
参考文献:ReactiveCocoa GitHub Repository, ReactiveSwift Source Code