Combine 学习笔记(四):Subject

本文我们着重来分析一种特殊的 Publisher —— Subject。与之前我们讨论的 Publisher 不同的是,Subject 的最大特点就是可以手动发送数据,本文将讨论 Subject 的定义以及基本用法。

一、Subject 的定义

public protocol Subject : AnyObject, Publisher {

    func send(_ value: Self.Output)

    func send(completion: Subscribers.Completion<Self.Failure>)

    func send(subscription: Subscription)

}

从定义可以看到,Subject 继承于 Publisher 协议并且暴露了 3 个 send 方法,我们可以通过调用 send 方法来手动发送 Output 数据以及 Completion 事件。

二、Combine 内置的 Subject

Combine 为我们内置了两种 Subject —— PassthroughSubject 与 CurrentValueSubject,它们的区别主要在于是否会对收到的数据进行保留。

PassthroughSubject

PassthroughSubject 通过 send 发送数据或事件给下游的 Publisher 或 Subscriber, 不会对接收到的数据进行保留。

import Combine

let subject = PassthroughSubject<String, Never>() // 创建PassthroughSubject

// 订阅
let subscription = subject.sink(receiveCompletion: { _ in
    print("receiveCompletion")
}, receiveValue: { value in
    print(value)
    
})

// 发送数据
subject.send("hello")
subject.send("world")
subject.send(completion: .finished)

/* 输出:
 hello
 world
 receiveCompletion
 */

CurrentValueSubject

与 PassthroughSubject 不同,CurrentValueSubject 会保留一个最后的数据,并在被订阅时将这个数据发送给下游的 Publisher 或 Subscriber。

import Combine

let subject = CurrentValueSubject<String, Never>("hi") // 创建CurrentValueSubject,需要给它赋一个初值

// CurrentValueSubject有value属性
print(subject.value)

// 发送数据
subject.send("hello")
print(subject.value)

subject.send("world")
print(subject.value)

// 订阅
let subscription = subject.sink { value in
    print(value)
}


/* 输出:
 hi
 hello
 world
 world
 */

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注