ReactiveCocoa-Swift部分入门指南-Signal
2016-07-29 11:12
501 查看
转载自:valiantcat
学习过ReactiCocoa(以下简称RAC)的同学一般都会使用Objective-C的部分,不过RAC3之后支持了Swift,目前RAC3.x支持的是Swift1.x系列,RAC4支持的是Swift2.x系列。今天花了一点时间学习了下Swift部分示例代码。这里做些记录。Swift是支持playground,可以使用Markdown编写文档,并且所见即所得的界面方便学习。更可以插入图片。方便阅读。
学习知识必备
Start
PlaygroundUtility
Signal
Subscription
empty
Never
Operators
uniqueValues 唯一值
map
mapError
filter
ignoreNil
take
collect
默认你已经学过RAC-OC部分, Swift语言,并对Monad,functional Programming有些简单的了解,或者,如果你学习了RXSwift更好。
先来观察一下这个里面有两个方法
scopedExample 方便测试,并分割日志输出,Error也是为了测试方便。
一个
信号通常被用来表示正在进行中的事件流,比如
-Driven)到任何观察者哪里,并且所有观察者都是同时收到这些事件。
如果你想访问一系列的事件,就必须
信号可以通过原函数去操作,比如
nextEvents生效(也就是对 comlete,failure等不生效)。
在一个信号的生命周期里,可以发送无数次的NextEvents事件,直到他们被终结,类似compleye,Faied,InterRuppet。终止事件没有数据值,所以他们必须被单独处理。
一个信号通常被用来表示正在进行中的事件流,有时候他们被叫做热信号,这意味这订阅者可以错过一些在它订阅前发送的事件。订阅一个信号不会触发任何附作用。
因为Swift有泛型的存在,这样的话我们可以把Signal当作任何数据类型的容器,而不是像OC中利用上帝类型(id)。更加方便传递数据。
首先我们通过Siganl.pipe()创建了一个信号和一个观察者。
奇怪的是,在RACOC部分中,我们很少主动创建观察者,我们通常直接订阅信号就可以。
在Siwft中,通过pipe创建的信号是个热信号,类似与OC中的RACSubject系列,在RACSubject继承自RACSiganl又继承自RACStream,RACStream是一个Monad,它可以代表数据和数据的一系列的操作如
RACSubject又遵守了RACSubscriber协议,这个协议定义了可以发送数据的操作。
所以RACSubject即是一个信号,又是一个观察者。
在Swift部分的实现中,Signal并没有实现发送数据的方法。所以它需要一个内部的Observer去发送数据。所以它被pipe直接返回,
在外部我们需要自己实例化一个Observer观察者。去观察(订阅)事件,
可能在你查看pipe的实现的时候并不太好理解。把尾随闭包补全相对好理解点。
做个总结
RACOC中:
RACSubject = RACSignal + RACSubscriper
在订阅的时候,订阅者被放在了RACSubject内部存放,我们只需要去关注订阅的block实现即可。
RACSwift中:
Signal:Just is a Signal
所以需要一个内部观者者去充当发送数据的工具。外部的订阅需要自己手动实例观察者
热信号:
由于pipe方法返回的是热信号,所以一个订阅者会错过在订阅之前发送的事件。
空信号直接发送一个interrupted事件
一个never信号不会发送任何事件
仅从集合中发送一次相同事件—类似与arrryQueue变成了SetQueue
注意:这会造成被发送的值被保留下来,用于以后发送的时候来检查是否重复,你可以编写一个函数来过滤重复值,这样可以减少内存消耗。
把每一个发送的值转换成新的值
ITDogFire-throne
学习过ReactiCocoa(以下简称RAC)的同学一般都会使用Objective-C的部分,不过RAC3之后支持了Swift,目前RAC3.x支持的是Swift1.x系列,RAC4支持的是Swift2.x系列。今天花了一点时间学习了下Swift部分示例代码。这里做些记录。Swift是支持playground,可以使用Markdown编写文档,并且所见即所得的界面方便学习。更可以插入图片。方便阅读。
学习知识必备
Start
PlaygroundUtility
Signal
Subscription
empty
Never
Operators
uniqueValues 唯一值
map
mapError
filter
ignoreNil
take
collect
学习知识必备
默认你已经学过RAC-OC部分, Swift语言,并对Monad,functional Programming有些简单的了解,或者,如果你学习了RXSwift更好。
Start
1. git clone git@github.com:ReactiveCocoa/ReactiveCocoa.git • 执行script/bootstrap 脚本 • 如果你安装了 [Cartheage](https://github.com/Carthage/Carthage) 使用 carthage checkout 2. 打开 ReactiveCocoa.xcworkspace 3. 编译 Result-Mac scheme 4. 编译 ReactiveCocoa-Mac scheme 5. 在workSpace目录中打开ReactiveCocoa.playground 6. Choose View > Show Debug Area、
PlaygroundUtility
先来观察一下这个里面有两个方法1 2 3 4 5 6 7 8 | public func scopedExample(exampleDescription: String, _ action: () -> Void) { print("\n--- \(exampleDescription) ---\n") action() } public enum Error: ErrorType { case Example(String) } |
Signal
一个Signal类型的实例,代表了一个有时序的并且可以被
观察(类似订阅)的
事件流
信号通常被用来表示正在进行中的事件流,比如
通知,
用户输入等。用户(或者只要能造成事件的东西)产生的事件发送或者被接受,事件就被传递到信号上,并且被
推送(push
-Driven)到任何观察者哪里,并且所有观察者都是同时收到这些事件。
如果你想访问一系列的事件,就必须
观察一个信号,观察一个信号并不会触发任何附作用,可以这样理解。信号是由生产者生产和推动(push)的,消费者(观察者)是不会对事件的生命周期有任何影响。在观察一个信号时,发送了什么事件,只能对这个事件做操作,因为信号是有时序的,不能随机的访问其他事件。
信号可以通过原函数去操作,比如
filter,
map,
reduce,也可以同时操作多个信号如
zip,这些原函数只在
nextEvents生效(也就是对 comlete,failure等不生效)。
在一个信号的生命周期里,可以发送无数次的NextEvents事件,直到他们被终结,类似compleye,Faied,InterRuppet。终止事件没有数据值,所以他们必须被单独处理。
SUBSCRIPTION
一个信号通常被用来表示正在进行中的事件流,有时候他们被叫做热信号,这意味这订阅者可以错过一些在它订阅前发送的事件。订阅一个信号不会触发任何附作用。1 2 3 4 5 6 7 89 | scopedExample("Subscription") { // Signal.pipe is a way to manually control a signal. the returned observer can be used to send values to the signal let (signal, observer) = Signal<Int, NonError>.pipe() let subscriber1 = Observer<Int, NonError>(next: { print("Subscriber 1 received \($0)") }) let subscriber2 = Observer<Int, NonError>(next: { print("Subscriber 2 received \($0)") }) print("Subscriber 1 subscribes to the signal") print("\(observer)") signal.observe(subscriber1) print("Send value `10` on the signal") // subscriber1 will receive the value observer.sendNext(10) print("Subscriber 2 subscribes to the signal") // Notice how nothing happens at this moment, i.e. subscriber2 does not receive the previously sent value signal.observe(subscriber2) print("Send value `20` on the signal") // Notice that now, subscriber1 and subscriber2 will receive the value observer.sendNext(20) } --- Subscription --- Subscriber 1 subscribes to the signal Observer<Int, NonError>(action: (Function)) Send value `10` on the signal Subscriber 1 received 10 Subscriber 2 subscribes to the signal Send value `20` on the signal Subscriber 1 received 20 Subscriber 2 received 20 |
首先我们通过Siganl.pipe()创建了一个信号和一个观察者。
奇怪的是,在RACOC部分中,我们很少主动创建观察者,我们通常直接订阅信号就可以。
在Siwft中,通过pipe创建的信号是个热信号,类似与OC中的RACSubject系列,在RACSubject继承自RACSiganl又继承自RACStream,RACStream是一个Monad,它可以代表数据和数据的一系列的操作如
map,
flattenMap,
bind
RACSubject又遵守了RACSubscriber协议,这个协议定义了可以发送数据的操作。
所以RACSubject即是一个信号,又是一个观察者。
在Swift部分的实现中,Signal并没有实现发送数据的方法。所以它需要一个内部的Observer去发送数据。所以它被pipe直接返回,
在外部我们需要自己实例化一个Observer观察者。去观察(订阅)事件,
可能在你查看pipe的实现的时候并不太好理解。把尾随闭包补全相对好理解点。
做个总结
RACOC中:
RACSubject = RACSignal + RACSubscriper
在订阅的时候,订阅者被放在了RACSubject内部存放,我们只需要去关注订阅的block实现即可。
RACSwift中:
Signal:Just is a Signal
所以需要一个内部观者者去充当发送数据的工具。外部的订阅需要自己手动实例观察者
热信号:
由于pipe方法返回的是热信号,所以一个订阅者会错过在订阅之前发送的事件。
EMPTY
空信号直接发送一个interrupted事件1 2 3 4 5 6 7 89 | scopedExample("`empty`") { let emptySignal = Signal<Int, NonError>.empty let observer = Observer<Int, NonError>( failed: { _ in print("error not called") }, completed: { print("completed not called") }, interrupted: { print("interrupted called") }, next: { _ in print("next not called") } ) emptySignal.observe(observer) } --- `empty` --- interrupted called |
NEVER
一个never信号不会发送任何事件1 2 3 4 5 6 7 89 | scopedExample("`never`") { let neverSignal = Signal<Int, NoError>.never let observer = Observer<Int, NoError>( failed: { _ in print("error not called") }, completed: { print("completed not called") }, interrupted: { print("interrupted not called") }, next: { _ in print("next not called") } ) neverSignal.observe(observer) } --- `never` --- |
Operators
UNIQUEVALUES
唯一值
仅从集合中发送一次相同事件—类似与arrryQueue变成了SetQueue注意:这会造成被发送的值被保留下来,用于以后发送的时候来检查是否重复,你可以编写一个函数来过滤重复值,这样可以减少内存消耗。
1 2 3 4 5 6 7 89 | scopedExample("`uniqueValues`") { let (signal, observer) = Signal<Int, NoError>.pipe() let subscriber = Observer<Int, NoError>(next: { print("Subscriber received \($0)") } ) let uniqueSignal = signal.uniqueValues() uniqueSignal.observe(subscriber) observer.sendNext(1) observer.sendNext(2) observer.sendNext(3) observer.sendNext(4) observer.sendNext(3) observer.sendNext(3) observer.sendNext(5) } --- `uniqueValues` --- Subscriber received 1 Subscriber received 2 Subscriber received 3 Subscriber received 4 Subscriber received 5 |
MAP
把每一个发送的值转换成新的值1 2 3 4 5 6 7 89 | scopedExample("`map`") { let (signal, observer) = Signal<Int, NoError>.pipe() let subscriber = Observer<Int, NoError>(next: { print("Subscriber received \($0)") } ) let mappedSignal = signal.map { $0 * 2 } mappedSignal.observe(subscriber) print("Send value `10` on the signal") observer.sendNext(10) } --- `map` --- Send value `10` on the signal Subscriber received 20 |
相关文章推荐
- swift闭包纯代码
- swift3.0 中NSNotification 的使用
- Amazon S3和Swift鉴权机制分析
- swift学习第二天
- Swift基础之代理与传值(一)
- Swift控制器加载xib Swift Controller'view load from xib
- Swift支持Amazon S3的机制及优化
- Swift根据日期字符串返回日期是星期几
- Swift:Command failed due to signal: Segmentation fault: 11
- swift - UIToolbar 的用法
- Swfit(1)
- swift alert 弹出框
- swift清除缓存实例
- Swift实现"视差效果"的视图轮播
- swift - UISegmentedControl 和 UIWebView 的用法
- swift 函数
- 如何在一个项目中是OC和Swift开发
- swift 基础语法
- IOS(swift语言)第4天可选类型(?!)初始化
- iOS程序执行流程(swift)