ReactiveCocoa 3.0 初窥

566 查看

本篇博文介绍了 ReactiveCocoa 3.0 (以下简称 RC)全新的 Swift 接口,包括泛型,操作符以及柯里化函数的有趣用法。

这是我为 RC3 系列准备的第一篇文章。这篇文章主要的侧重点是介绍 Swift 版本的 Signal 类,在下一期文章中我会展示一个更完整的应用。

引言

我成为RC的粉丝已经很久了,Ray Wenderlich 网站上已经有我发表的数篇文章,以及一些与 RC 相关的幻灯片。

在Swift问世之初,我们就可以利用桥接 Objective-C 版的 RC 接口在 Swift 中使用 RC。但是能够充分利用 Swift 的特性,如泛型等,会使得 Swift RC 更加纯粹完美!

感谢 RC 团队,他们在过去的几个月里一直工作在全新的 Swift RC 分支上。就在一周前第一个 beta 版本问世,也就是今天这篇文章的主角。

在阅读这篇文章我假定您已经有了一定的 RC 基础,当然,您不用成为一个顶级专家。

创建 SIGNALS

使用 Cathage 可以在项目中非常方便的引入 RC,在工程的根目录创建一个 Cartfile 文件引用 RC3:

如文档所述,运行 carthage update.

RC3 包含了全新的 Swift API,同时也兼容 Objective-C。所以你会发现两个 Signal 类, Obj-C 版本的 RACSignal 以及 Swift 版本的 Signal

Swift 版本的 Signal 类一个重要特性就是它是泛型的:

类型参数 T 表明 Signal 对象发出的 ‘next’ 事件所附带的数据类型,错误类型由 E 表示,并要求实现 ErrorType 协议。 Swift 的 signals 类与 OC 版本具有类似的用法,下面展示了一个每秒抛出事件的 signal 类:

Signal 类的初始化方法需要传入一个生成器,在上例中传入的是一个闭包。生成器被调用后传入一个 sink 对象,sink 对象的类型是 SinkOf<Event<String, NoError>>。任何发送给 sink 对象的事件都会被 signal 对象抛出。

sendNext 函数把局部变量 count 作为第二个参数,构造了一个事件传递给 sink。

Swift Signal 类与 ObjC 版本的 Signal 类有相似的内存管理机制,当一个 signal 实例生命周期结束时,需要被释放。在上例中这一步被包含在闭包表达式之中的最后一步

监听 SIGNALS

有若干种方法你可以监听一个 Signal。最简单的方法是使用 observe 方法,为你所感兴趣的事件提供一个函数或者闭包回调。

这是一个监听 next 事件的例子:

输出如下:

或者,你可以提供一个 sink 变量监听 signal 的时间:

Event 类型是一个枚举,关联了 next 和 error 事件。Sinkof 初始化方法构造了一个 SinkOf<Event<String, NoError>> 类型的sink 变量,同样的,后面的闭包表达式作为参数传给了初始化方法。

由于 Swift 语言的限制,Event 类型的枚举(next,error 事件)携带的数据被 LlamaKit Box 类封装在暗盒中,作为一个 RC3 的使用者你很少需要直接跟 Event 类型打交道,有很多 API 可以帮你进行封装和解封的操作。

上面的例子展示了些许 Swift 跟 RC 结合所带来的优势。使用泛型定义 Signal 意味着监听事件时可以更安全的获取数据类型,此外,如果你使用的是很复杂的泛型嵌套,你也不用去显式的声明泛型了。

转换 SIGNALS

Swift Signal 类型与它的 Objc 版本具有诸多相似的特性.可是,他们之间有一个根本的区别。

对于一个简单的map操作,你通常会定义一个Signal的方法,伪代码如下:

不过,map 函数以及其他能应用于 Signal 的操作实际上都是非成员函数: