ReactiveCocoa
前言RAC 简介: RAC 的V2.5的类图 <= v2.5 :Objective-C ; ReactiveCocoa就是根据 Monad 的概念搭建起来的 一个 Monad 就是一种实现了 Monad typeclass 的数据类型。 ReactiveCocoa 主要由以下四大核心组件构成:信号源:RACStream 及其子类; 信号源又是最核心的部分,其他组件都是围绕它运作的 它使用信号来代表这些异步事件,提供了一种统一的方式来处理所有异步的行为,包括代理方法、block 回调、target-action 机制、通知、KVO 等: // 代理方法
[[self
rac_signalForSelector:@selector(webViewDidStartLoad:)
fromProtocol:@protocol(UIWebViewDelegate)]
subscribeNext:^(id x) {
// 实现 webViewDidStartLoad: 代理方法
}];
// target-action
[[self.avatarButton
rac_signalForControlEvents:UIControlEventTouchUpInside]
subscribeNext:^(UIButton *avatarButton) {
// avatarButton 被点击了
}];
// 通知
[[[NSNotificationCenter defaultCenter]
rac_addObserverForName:kReachabilityChangedNotification object:nil]
subscribeNext:^(NSNotification *notification) {
// 收到 kReachabilityChangedNotification 通知
}];
// KVO
[RACObserve(self,username) subscribeNext:^(NSString *username) {
// 用户名发生了变化
}];
ReactiveCocoa的作用ReactiveCocoa为事件提供了很多处理方法 比如按钮的点击使用action,ScrollView滚动使用delegate,属性值改变使用KVO等系统提供的方式来处理事件响应。其实这些事件,都可以通过RAC处理
利用RAC处理事件:可以把要处理的事情,和监听的事情的代码放在一起,这样非常方便我们管理,就不需要跳到对应的方法里。非常符合我们开发中高聚合,低耦合的思想。 RAC 的特点它真正强大的地方在于我们可以对这些不同的信号进行任意地组合和链式操作,从最原始的输入 input 开始直至得到最终的输出 output 为止 [[[RACSignal
combineLatest:@[ RACObserve(self,username),RACObserve(self,password) ]
reduce:^(NSString *username,NSString *password) {
return @(username.length > 0 && password.length > 0);
}]
distinctUntilChanged]
subscribeNext:^(NSNumber *valid) {
if (valid.boolValue) {
// 用户名和密码合法,登录按钮可用
} else {
// 用户名或密码不合法,登录按钮不可用
}
}];
如何导入ReactiveCocoa框架通常都会使用CocoaPods(用于管理第三方框架的插件)帮助我们导入。 进入终端,建立 Podfile,并且输入以下内容 platform :ios,'8.0'
use_frameworks!
target 'KNTestReactiveCocoa' do
pod 'ReactiveCocoa','~> 4.1.0'
end
版本说明: 2.5 纯 OC 3.0 正式版支持 Swift 1.2 4.0 测试版支持 Swift 2.0 在终端输入以下命令安装框架 $ pod install
注意:目前只有使用2.5 才能编译成功。 platform :ios,'~> 2.5'
end
ReactiveCocoa常见类在RAC中最核心的类RACSiganl RACSiganl:信号源代表的是随着时间而改变的值流。 next :RACSignal 通过 next 事件向订阅者传送新的值,并且这个值可以为 nil ;
error :RACSignal 通过 error 事件向订阅者表明信号在正常结束前发生了错误;
completed :RACSignal 通过 completed 事件向订阅者表明信号已经正常结束,不会再有后续的值传送给订阅者。
通常情况下,一个信号的生命周期是由任意个 next 事件和一个 error 事件或一个 completed 事件组成的。 RACEmptySignal :空信号,用来实现 RACSignal 的 +empty 方法;
RACReturnSignal :一元信号,用来实现 RACSignal 的 +return: 方法;
RACDynamicSignal :动态信号,使用一个 block 来实现订阅行为,我们在使用 RACSignal 的 +createSignal: 方法时创建的就是该类的实例;
RACErrorSignal :错误信号,用来实现 RACSignal 的 +error: 方法;
RACChannelTerminal :通道终端,代表 RACChannel 的一个终端,用来实现双向绑定。
对于 RACSignal 类簇来说,最核心的方法莫过于 -subscribe: 了,这个方法封装了订阅者对信号源的一次订阅过程,它是订阅者与信号源产生联系的唯一入口。因此,对于 RACSignal 的所有子类来说,这个方法的实现逻辑就代表了该子类的具体订阅行为,是区分不同子类的关键所在。 信号类,一般表示将来有数据传递,只要有数据改变,信号内部接收到数据,就会马上发出数据。 注意: 信号类(RACSiganl),只是表示当数据改变时,信号内部会发出数据,它本身不具备发送信号的能力,而是交给内部一个订阅者去发出。 默认一个信号都是冷信号,也就是值改变了,也不会触发,只有订阅了这个信号,这个信号才会变为热信号,值改变了才会触发。 如何订阅信号:调用信号RACSignal的subscribeNext就能订阅。 GitHub代码 RACStreamRACStream 是 ReactiveCocoa 中最核心的类,代表的是任意的值流,它是整个 ReactiveCocoa 得以建立的基石,下面是它的继承结构图: RACSubscriber:表示订阅者的意思,用于发送信号,这是一个协议,不是一个类,只要遵守这个协议,并且实现方法才能成为订阅者。通过create创建的信号,都有一个订阅者,帮助他发送数据。 + (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe;
RACDisposable:用于取消订阅或者清理资源,当信号发送完成或者发送错误的时候,就会自动触发它。 它封装了取消和清理一次订阅所必需的工作。它有一个核心的方法 -dispose ,调用这个方法就会执行相应的清理工作,这有点类似于 NSObject 的 -dealloc 方法。RACDisposable 总共有四个子类,它的继承结构图如下: RACSerialDisposable :作为 disposable 的容器使用,可以包含一个 disposable 对象,并且允许将这个 disposable 对象通过原子操作交换出来; 小结:在合适的时机调用 disposable 对象的 -dispose 方法 RACSubject: RACSubject 继承自 RACSignal ,所以它可以作为信号源被订阅者订阅,同时,它又实现了 RACSubscriber 协议,所以它也可以作为订阅者订阅其他信号源,这个就是 RACSubject 为什么可以手动控制的原因。 RACSubject:信号提供者,自己可以充当信号,又能发送信号。 使用场景:通常用来代替代理,有了它,就不必要定义代理了。 在 MVVM 中使用 RACSubject 可以非常方便地实现统一的错误处理逻辑。 另外,RACSubject 也有三个用来实现不同功能的子类:RACGroupedSignal :分组信号,用来实现 RACSignal 的分组功能; RACReplaySubject:重复提供信号类,RACSubject的子类。 RACReplaySubject可以先发送信号,在订阅信号,RACSubject就不可以。 使用场景: 一:如果一个信号每被订阅一次,就需要把之前的值重复发送一遍,使用重复提供信号类。
二:可以设置capacity数量来限制缓存的value的数量,即只缓充最新的几个值。
RACSubject和RACReplaySubject简单使用 RACTuple:元组类,类似NSArray,用来包装值. RACSequence:RAC中的集合类,用于代替NSArray,NSDictionary,可以使用它来快速遍历数组和字典。 RACCommand:RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程。 使用场景:监听按钮点击,网络请求 RACMulticastConnection使用注意: RACMulticastConnection通过RACSignal的-publish或者-muticast:方法创建.
RACScheduler:RAC中的队列,用GCD封装的。 RACUnit :表?stream不包含有意义的值,也就是看到这个,可以直接理解为nil. RACEvent:把数据包装成信号事件(signal event)。它主要通过RACSignal的-materialize来使用。 二、 iOS Reactive Cocoa的常见用法.1 代替代理: rac_signalForSelector:用于替代代理。 rac_valuesAndChangesForKeyPath:用于监听某个对象的属性改变。 rac_signalForControlEvents:用于监听某个事件。 rac_addObserverForName:用于监听某个通知。 rac_textSignal:只要文本框发出改变就会发出这个信号。 rac_liftSelector:withSignalsFromArray:Signals:当传入的Signals(信号数组),每一个signal都至少sendNext过一次,就会去触发第一个selector参数的方法。 // KNTestRACMethodTool.h 总结RAC的信号机制很容易将某一个Model变量的变化与界面关联,所以非常容易应用Model-View-ViewModel 框架。通过引入ViewModel层,然后用RAC将ViewModel与View关联,View层的变化可以直接响应ViewModel层的变化,这使得Controller变得更加简单,由于View不再与Model绑定,也增加了View的可重用性。 RAC主要解决了三个问题:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |