最近项目不多,所以就研究了一下RxSwift和RAS,RAC以前项目中用过了,在这里我就先简单的介绍一下什么是RAS。
总述:
在RAC 5.0这个版本,有了很大的改动,API已经重新命名。在和Swift相关的部分被抽调出来搞成了一个新的框架:ReactiveSwift,可见苹果爸爸对小儿子的喜爱,要大力推广swift了,而不仅仅是用于苹果开发中。
改动部分:
1. RACSignal 和 SignalProducer、 Signal
2. RACCommand 和 Action
3. RACScheduler 和 SchedulerType
4. RACDisposable 和 Disposable
简介:
首先我们用<code>cocoapod</code>导入
pod 'ReactiveCocoa'
然后再项目里导入头文件
import ReactiveCocoa
import ReactiveSwift
import Result
import enum Result.NoError
如果你只导入了 <code>ReactiveSwift</code>而没有导入<code>Result</code>,那你打<code>NoError</code>就会报错,因为<code>NoError</code> 依赖于<code> Result</code>,
如果你没有导入<code>import enum Result.NoError</code>,<code>NoError</code>是不会提醒的
主要类型
1.事件(Events)
一个事件,被表示为一个 <code>Event</code> 类型,它表示一些事情发生了。在 <code>ReactiveSwift</code>中, 事件是通讯的核心。一个事件可能表示一个按钮被按下了、从<code> API</code>中接收到了一条信息或是一次长时间操作的完成。在任何情况下,有一定意义的事情产生了事件,并通过 <code>信号</code> 发送它们给了<code>观察者</code>。
Event
是一个枚举值,它可以表示为一个 <code>值事件(value)</code> 或者 三个<code>终止操作</code>的任意一个:
a. <code>值事件(value)</code>可以从来源处提供一个值。
b. 失败事件表示在信号正常结束之前发生了错误。该事件被<code> ErrorType</code>类型所参数化,这个类型表明事件允许出现失败。但是如果失败是不被允许的,事件将提供<code> NoError</code>类型来阻止失败。
c. 完成事件表明信号成功地结束了,并且<code>源处(source)</code>不在发送其他任何值了。
d. 中止事件意味着操作可能成功也可能没有成功。
2. 信号(Signals)
一个信号,被表示为一个 <code>Signal </code>类型,是可以观察的 事件 的一组序列。
信号通常被用来表示正在进行的 <code>事件流(event streams)</code>,比如通知、用户输入等等。随着工作的进行和数据被接受,事件基于信号被发送,信号能把事件推送给任何的观察者。
所有的观察者能同时看到事件。
用户如果想获取一个事件,就必须观察一个信号。观察一个信号不会造成任何的副作用。换言之,信号完全是 <code>生产者驱动的(producer-driven)</code>和 <code>基于推送的(push-based)</code>,并且<code>消费者(观察者)</code>在它们的生命周期中不会有任何影响。在观察信号的时候,用户只能用它们(事件)在信号中被发送的顺序相同的序列来评估它们。我们不能随机的访问信号的值。
信号可以通过应用原语[primitives]来控制它们,比如 <code>filter</code>、<code>map</code>和 <code>reduce</code>都是可以操作一个信号的典型原语。值得注意的是,原语操作仅能对 值事件 进行操作。
在一个信号的生命周期中,它可能有无数的 值事件,并且会以一个终止事件而结束(失败事件、完成事件、中止事件的任意一个)。终止事件不能被包含在信号的值中,它们必须被单独处理。
3. 管道(Pipes)
一个管道,是被 <code>Signal.pipe() </code>创建的,是一个能被手动控制的信号。
这个方法返回一个信号和观察者。这个信号能够通过发送事件给观察者的方式被控制。这对于连接 非RAC 的代码是非常有用的。
举个栗子,比如在 block 回调函数中处理应用程序逻辑,这些块能简单地向观察者发送事件。同时,题目也可以返回信号,并隐藏回调的实现细节。
4. 信号发生器(Signal Producers)
一个信号发生器,可以被表示为一个 <code>SignalProducer</code>类型,它能创建信号,并且会产生副作用。
它们能被用来表示一些操作或者任务,比如网络请求,在每次调用 <code>start()</code>时都将创建一个新的基本操作,并允许调用者去观察结果。<code>startWithSignal()</code>变型可以访问所产生的信号,如果需要的话,允许它被观察多次。
因为 <code>start() </code>的行为,由相同发生器创建的信号可能会有不同序列或版本的事件,也许流也是完全不同。与普通的信号不同,在增加一个观察者之前,它不会开始工作(不会产生事件),而且每增加一个额外的观察者就会重新工作一遍。
开始一个信号发生器会返回一个<code>disposable</code>,disposable被用于中止/关闭与产生的信号相关的工作。
就像和信号一样,信号发生器也能通过<code>原语(primitives)</code>被控制,比如 map、filter等等。每一个信号原语都能使用 lift方法去操作信号产生器。此外,这里还有可以控制 when和 how的额外原语,比如 times。
5. 观察者(Observers)
一个观察者可以是任意东西,只要它正在等待或者即将等待信号中的事件。在 RAC中,一个观察者被表示成一个能接收 <code>Event</code>的 <code>Observer</code>。
观察者是通过使用基于闭包的 <code>Signal.observe</code>或者是 <code>SignalProducer.start</code>方法隐式创建的。
6. 动作(Actions)
一个动作,被表示为 <code>Action</code> 类型。当动作在执行的时候,它可能产生0个或者多个输出,也可能出现失败。
动作对于在用户交互中执行有副作用的工作时非常有用,比如按下一个按钮。动作也会基于一个 [属性] 变得自动不可用,这种不可用状态能够在 UI中通过禁用某些操作的方式被表示出来。
7. 属性(Properties)
一个属性,被表示为一个 <code>PropertyProtocol</code> 类型。它能存储一个值,并能通知观察者关于这个值得将来的变更。
一个属性的当前值可能被包含在这个值的 getter里面。产生器 getter 会返回一个 <code>信号产生器</code> ,这个信号产生器会发送属性的当前值,这个值会随着时间的推移而变化。 信号 getter
不仅仅会发送初始化值,也会随着时间发送所有的改变。
<code><~ </code>操作可以被用来以用不同的方式绑定属性。在任何情况下,目标都一定会成为绑定目标,它被表示为 <code>BingingTargetProtocol</code>。所有可变的属性类型,都被表示为 <code>MutablePropertyProtocol</code>,是内在的绑定目标。
property <~ signal: 将一个信号绑定在一个属性身上,更新这个属性值的时候,信号会发送出这个属性的最新值。
property <~ producer: 启动一个给定的信号产生器,并将属性的值绑定到信号发送的最新值上。
property <~ otherProperty: 将一个属性绑定在另一个属性身上,所以一旦源属性的值更新了,目标属性的值也会随之更新。
属性提供了大量的事务操作,比如 map、combineLatest或者是 zip,这些操作与信号和信号产生器中的相似。
8. Disposables
一个 Disposable,会被表示成<code>Disposable</code> 协议,是一个内存管理和取消的机制。当启动一个信号产生器的时候,会返回一个 disposable。disposable能取消已启动的工作(比如后台处理,网络请求等),清除所有临时资源,然后用创建的特定信号来发送一个最终的中止事件。观察一个信号也会返回一个 disposable。处理它将会阻止观察者接受来自信号的未来的事件,但它不会对信号本身有任何影响。
9. 调度器(Schedulers)
一个调度器,会被表示成一个 <code>SchedulerProtocol</code>协议,它是一个串行的可执行队列,这些队列被用于执行工作或交付(传递)结果。信号和信号产生器能被命令在特定的调度器上传递程序。信号产生器还能被用来在特定的调度器上开始它们的工作。调度器与 Grand Central Dispatch队列相似,但是调度器支持取消操作(通过 <code>disposables</code>),并且始终按串行方式去执行。[ImmediateScheduler
] 是一个例外,该调度器不提供同步执行。这能帮助避免死锁,并且鼓励用信号和信号产生器的原语操作去代替闭包。
调度器和 <code>NSOperationQueue</code>也有一定的相似,但是调度器不允许任务被重新安排或者依赖另外一个任务。
主要用法:
信号的创建
不多说了直接上代码
咯咯
下面是打印的结果
接下来我们创建一个热信号,看看是什么结果,what?你说你不知道什么是热信号,什么是冷信号。好吧
热信号是主动的,即使你没有订阅事件,它仍然会时刻推送。而冷信号是被动的,只有当你订阅的时候,它才会发送消息。
热信号可以有多个订阅者,是一对多,信号可以与订阅者共享信息。而冷信号只能一对一,当有不同的订阅者,消息会从新完整发送。
我们来看一下热信号吧,还是废话不多说,代码见真知