ReactiveCocoa(简称RAC)是最初由GitHub团队开发的一套基于Cocoa的FRP框架。FRP即Functional Reactive Programming(函数式响应式编程),其优点是用随时间改变的函数表示用户输入,这样就不需要可变状态了。我们之 前的文章“RACSignal的Subscription深入分析”里曾经详细讲解过RAC核心概念之一RACSignal的实现原理。在美团客户端中,我们大量使用了这个框架。冷信号与热信号的概念很容易混淆并造成一定的问题。鉴于这个问题具有一定普遍性,我将用一系列文章讲解RAC中冷信号与热信号的相关知识点,希望可以加深大家的理解。本文是系列文章的第一篇。 p.s. 以下代码和示例基于ReactiveCocoa v2.5。
ReactiveCocoa 4 如何使用冷热信号
. 每天开发我们都在alloc对象,而alloc方法做了些什么呢. ReactiveCocoa 中 RACSignal 是如何发送信号的 - 掘金 前言 ReactiveCocoa是一个(第一个?)将函数响应式编程范例带入Objective-C的开源库。ReactiveCocoa是由Josh Abernathy和Justin Spahr-Summers .
iOS 进阶必读 - 收藏集 - 掘金
. 每天开发我们都在alloc对象,而alloc方法做了些什么呢. ReactiveCocoa 中 RACSignal 是如何发送信号的 - 掘金前言 ReactiveCocoa是一个(第一个?)将函数响应式编程范例带入Objective-C的开源库。ReactiveCocoa是由Josh Abernathy和Justin Spahr-Summers .
iOS 进阶必读
. 1.Runtime 的优点 (1) 实现多继承 Multiple Inheritance (2) Met… ReactiveCocoa 中 RACSignal 所有变换操作底层实现分析(上) 前言 在上篇文章中,详细分析了RACSignal是创建和订阅的详细过程。看到底层源码实现后,就能发现,ReactiveCocoa这个FRP.
iOS 进阶必读
. 1.Runtime 的优点 (1) 实现多继承 Multiple Inheritance (2) Met… ReactiveCocoa 中 RACSignal 所有变换操作底层实现分析(上) 前言 在上篇文章中,详细分析了RACSignal是创建和订阅的详细过程。看到底层源码实现后,就能发现,ReactiveCocoa这个FRP.
走进ReactiveCocoa的世界
在学习ReactiveCocoa之前,先学习一下概念 ReactiveCocoa 是一套开源的基于Cocoa的FRP框架 .FRP的全称是Functional Reactive Programming,中文译作函数式响应式编程,是RP(Reactive Programm,响应式编程)的FP(Functional Programming,函数式编程).
细说ReactiveCocoa的冷信号与热信号系列(1)
ReactiveCocoa(简称RAC)是最初由GitHub团队开发的一套基于Cocoa的FRP框架。FRP即Functional Reactive Programming(函数式响应式编程),其优点是用随时间改变的函数表示用户输入,这样就不需要可变状态了。我们之 前的文章“RACSignal的Subscription深入分析”里曾经详细讲解过RAC核心概念之一RACSignal的实现原理。在美团客户端中,我们大量使用了这个框架。冷信号与热信号的概念很容易混淆并造成一定的问题。鉴于这个问题具有一定普遍性,我将用一系列文章讲解RAC中冷信号与热信号的相关知识点,希望可以加深大家的理解。本文是系列文章的第一篇。 p.s. 以下代码和示例基于ReactiveCocoa v2.5。
什么是冷信号与热信号
冷热信号的概念源于.NET框架Reactive Extensions(RX)中的Hot Observable和Cold Observable,两者的区别是:
- Hot Observable是主动的,尽管你并没有订阅事件,但是它会时刻推送,就像鼠标移动;而Cold Observable是被动的,只有当你订阅的时候,它才会发布消息。
- Hot Observable可以有多个订阅者,是一对多,集合可以与订阅者共享信息;而Cold Observable只能一对一,当有不同的订阅者,消息是重新完整发送。
我们可以看到,信号在18:33:21.681时被创建,18:33:21.793依次接到1、2、3三个值,而在18:33:22.683再依次接到1、2、3三个值。说明了变量名为 signal 的这个信号,在两个不同时间段的订阅过程中,分别完整地发送了所有的消息。
- 创建了一个信号,在1秒、2秒、3秒分别发送1、2、3这三个值,4秒发送结束信号。
- 对这个信号调用publish方法得到一个RACMulticastConnection。
- 让connection进行连接操作。
- 获得connection的信号。
- 分别在1.1秒和2.1秒订阅获得的信号。
首先告诉大家 - [RACSignal publish] 、 - [RACMulticastConnection connect] 、 - [RACMulticastConnection signal] 这几个操作生成了一个热信号。 我们再来关注下输出结果的一些细节:
细说ReactiveCocoa的冷信号与热信号(一)
ReactiveCocoa(简称RAC)是最初由GitHub团队开发的一套基于Cocoa的FRP框架。FRP即Functional Reactive Programming(函数式响应式编程),其优点是用随时间改变的函数表示用户输入,这样就不需要可变状态了。我们之前的文章“RACSignal的Subscription深入分析”里曾经详细讲解过RAC核心概念之一RACSignal的实现原理。在美团客户端中,我们大量使用了这个框架。冷信号与热信号的概念很容易混淆并造成一定的问题。鉴于这个问题具有一定普遍性,我将用一系列文章讲解RAC中冷信号与热信号的相关知识点,希望可以加深大家的理解。本文是系列文章的第一篇。
p.s. 以下代码和示例基于ReactiveCocoa v2.5。
什么是冷信号与热信号
冷热信号的概念源于.怎么处理冷信号与热信号 NET框架Reactive Extensions(RX)中的Hot Observable和Cold Observable,两者的区别是:
- Hot Observable是主动的,尽管你并没有订阅事件,但是它会时刻推送,就像鼠标移动;而Cold Observable是被动的,只有当你订阅的时候,它才会发布消息。
- Hot Observable可以有多个订阅者,是一对多,集合可以与订阅者共享信息;而Cold Observable只能一对一,当有不同的订阅者,消息是重新完整发送。
- 创建了一个信号,在1秒、2秒、3秒分别发送1、2、3这三个值,4秒发送结束信号。 怎么处理冷信号与热信号
- 对这个信号调用publish方法得到一个RACMulticastConnection。
- 让connection进行连接操作。
- 获得connection的信号。
- 分别在1.1秒和2.1秒订阅获得的信号。
首先告诉大家- [RACSignal publish]、- [RACMulticastConnection connect]、- [RACMulticastConnection signal]这几个操作生成了一个热信号。
我们再来关注下输出结果的一些细节:
ReactiveCocoa 中 RACSignal 冷信号和热信号底层实现分析
RACReplaySubject 和 RACSubject 的区别在于,RACReplaySubject还会把历史的信号值都存储起来发送给订阅者。这一点,RACReplaySubject更像是RACSingnal 和 RACSubject 的合体版。RACSignal是冷信号,一旦被订阅就会向订阅者发送所有的值,这一点RACReplaySubject和RACSignal是一样的。但是RACReplaySubject又有着RACSubject的特性,会把所有的值发送给多个订阅者。当RACReplaySubject发送完之前存储的历史值之后,之后再发送信号的行为就和RACSubject完全一致了。
三. RACSignal冷信号
1.RACEmptySignal
2. RACReturnSignal
3. RACDynamicSignal
4. RACErrorSignal
5. RACChannelTerminal
四. 冷信号是如何转换成热信号的
在ReactiveCocoa v2.5中,冷信号转换成热信号需要用到RACMulticastConnection 这个类。
这里出现了一个不多见的函数OSAtomicCompareAndSwap32Barrier,它是原子运算的操作符,主要用于Compare and swap,原型如下:
OSAtomicIncrement32Barrier 和 OSAtomicDecrement32Barrier也是原子运算的操作符,分别是+1和-1操作。在autoconnect为了保证线程安全,用到了一个subscriberCount的类似信号量的volatile变量,保证第一个订阅者能连接上。返回的新的信号的订阅者订阅RACSubject,RACSubject也会去订阅内部的sourceSignal。
1. multicast:
2. publish
3. replay
4. replayLast
replayLast 和 replay的实现基本一样,唯一的不同就是传入的RACReplaySubject的Capacity是1,意味着只能保存最新的值。所以使用replayLast,订阅之后就只能拿到原信号最新的值。
5. replayLazily
replayLazily 的实现也和 replayLast、replay实现很相似。只不过把connect放到了defer的操作里面去了。
defer 单词的字面意思是延迟的。也和这个函数实现的效果是一致的。只有当defer返回的新信号被订阅的时候,才会执行入参block( )闭包。订阅者会订阅这个block( )闭包的返回值RACSignal。
block( )闭包被延迟创建RACSignal了,这就是defer。如果block( )闭包含有和时间有关的操作,或者副作用,想要延迟执行,就可以用defer。
then的操作也是延迟,只不过它是把block( )闭包延迟到原信号发送complete之后。通过then信号变化得到的新的信号,在原信号发送值的期间的时间内,都不会发送任何值,因为ignoreValues了,一旦原信号sendComplete之后,就紧接着block( )闭包产生的信号。
关于ReactiveCocoa v2.5中,冷信号即使转换成了热信号,热信号在之后的变换中还会在变成冷信号,所以在v2.5的版本中会有很多冷信号转成热信号的操作。在ReactiveCocoa v3.0以后的版本中,新增了热信号变换之后还是热信号的机制,如此以来就方便很多,不需要增加很多不必要的冷信号转成热信号的代码。
I'm @halfrost,Gopher / Apple Developer & Apple Teacher / Vuer / Machine Learning / Retired acmer / Math / Philosophy / Technical Writer.