阅读须知:本文重点关注这三者的基本用处和区别,对于三者的详细说明在此不做介绍,有需要的读者推荐阅读:链接: Swift Combine 入门导读

1. Publisher 用法

在最简单的情况下我们使用 Publisher 和 sink 来实现一个简单的数据流

import Combine

let publisher = ["Here","we","go!"].publisher

let subscription = publisher.sink { value in

print("subs received value: \(value)")

}

// 运行结果

//subs received value: Here

//subs received value: we

//subs received value: go!

在上面的案例中,publisher 初始化存储了一些数据,并且在被订阅后将这些数据逐个发出。这些数据发送完毕后,订阅者会收到一个完成的通知,并且这条管道会被关闭。当然,我们可以在下面再次使用 publisher.sink 订阅这些数据,这些数据会被再次逐个发送给新的订阅者。

2. PassthroughSubject 用法

想必大家看完上面的Publisher案例后都会产生疑问,因为我们在开发中大部分时间都是需要根据需要随时发布消息,而不是发布一条已经确定的数据流,我们如何实现随时插入数据呢,接下来我们就会用到 Subject。Subject 通常是一个中间代理,但是他不仅可以作为代理,还可以独立作为一个 Publisher 来发布消息。

独立作为Publisher示例代码,请仔细阅读注释理解

import Combine

// 初试化了一个 Subject,定义发布数据类型为 String 而且 Never 报错,更详细的用法请阅读文章开头的推荐链接

let pubSubject = PassthroughSubject()

// 在订阅之前 Send 的消息会丢失

pubSubject.send("订阅之前发送会丢失的数据")

let subscription = pubSubject.sink { value in

print("subscription1 received value: \(value)")

}

pubSubject.send("Hello")

pubSubject.send("World!")

// 发送 (completion: .finished) 代表全部发完了,通知订阅结束

pubSubject.send(completion: .finished)

pubSubject.send("订阅已经收到了结束的通知,这条没用了!")

// 运行结果

//subscription1 received value: Hello

//subscription1 received value: World

在上面的例子里我们使用 PassthroughSubject 初试化了一个发布者,可以使用Send发布消息,但是需要注意的是,在被订阅之前,Send的数据都是无效的,都会丢失。

作为中间代理,使用 Publisher.subscribe(_Subject)

import Combine

let observeSubject = PassthroughSubject()

let subscription = observeSubject.sink { value in

print("observeSubject received value: \(value)")

}

observeSubject.send("主动发布消息")

// 使用publisher.subscribe(Subject),可以将publisher的数据逐个发送到Subject里进行处理;

let publisher = ["Publisher发布消息","发布","消息"].publisher

publisher.subscribe(observeSubject)

// 因为在1中publisher的用法中我们说过,这些publisher数据发送完毕后,会发送一个完成的通知

// 就相当于上面的 publisher 还发了一个 .send(completion: .finished) ,因此这个订阅已经结束,后面主动发消息没用

observeSubject.send("这里发的消息收不到了,为什么呢,看上面注释")

在上面的例子里我们介绍了 publisher.subscribe(_Subject) , 其实开发中也很少用到,为了保持统一性和阅读性我们还是习惯用Subject.send来发送各种消息,和信号。

3. CurrentValueSubject

CurrentValueSubject 和 PassthroughSubject 完全类似,区别在于 CurrentValueSubject 会始终记录下之前发送的值,并在订阅后将当前的记录值发出去。

import Combine

let subject = CurrentValueSubject("初始化值,如果没被覆盖,订阅时会先收到我")

// 此时在订阅之前发的(最新的一个)消息就不会漏掉了。

subject.send("我就随便发一下,覆盖掉上次发送的值,被记录下来")

// 订阅时会先把当前记录的值发出去。

let subscription = subject.sink { value in

print("observeSubject received value: \(value)")

}

subject.send("Hello World")

let publisher = ["Here","we","go!"].publisher

publisher.subscribe(subject)

// 运行结果

// subject received value: 我就随便发一下,会被记录下来,而且覆盖掉上次发送的值

// subject received value: Hello World

// subject received value: Here

// subject received value: we

// subject received value: go!

本文参考链接:

Swift Combine 入门导读: https://www.jianshu.com/p/a4f1a263eabb

强烈推荐:

用 Xcode Playground 学习 Combine:https://github.com/AvdLee/CombineSwiftPlayground

推荐文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: