前面也说了RAC配合MVVM使用才能发挥最大的作用,因为RAC可以在VM模块中进行业务逻辑和网络请求,所以可以说完全分担了控制器的压力。
一:RAC的核心是RACSignal类(信号)
RACSignal: 就 RAC 来说是构造单元. 它代表我们最终将要收到的信息. 当你能将未来某时刻收到的消息具体表示出来时, 你可以开始预先运用逻辑并构建你的信息流,而不是必须等到事件发生才执行。白话一点就是最后我是一定会收到消息的,所以不需要考虑我是否能收到,只需要构建信息流就行。
那么什么是信号?
其实信号就是发送一系列的值,(三种事件:next、complete、error。你可以理解为我们生活中手机信号,需要一个设备来获取信号,那么谁是设备呢?这里就需要一个订阅者来监听这个信号。
信号是一些等待某事发生的异步代码, 然后把结果值发送给它们的订阅者. 你可以用 RACSignal
的类方法 createSignal:
RACSignal *Signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NetworkOperation *operation = [NetworkOperation getJSONOperationForURL:@"http://someurl"];
[operation setCompletionBlockWithSuccess:^(NetworkOperation *theOperation, id *result) {
[subscriber sendNext:result];//发送信号
[subscriber sendCompleted]; //如果不发送信号,这里就会取消信号
}
failure:^(NetworkOperation *theOperation, NSError *error) {
[subscriber sendError:error];
}];
我在成功的 block 里使用提供的
subscriber
对象调用 sendNext:
和 sendCompleted:
方法, 或在失败的 block 中调用 sendError:
. 现在我可以订阅这个信号并将在响应返回时接收到 json 值或是 error。
什么是订阅者(RACSubscriber)?
简言之, 它是等待信号给它发送一些值, 然后订阅者就能处理这些值了.,可以用subscribeNext:方法来获取信息
//这里的x值就是信号发送过来的值
[Signal subscribeNext:^(id* x) {
NSLog(@"%@",x);
}];
记下来讲解几个重要的事件:
信号延时:
<span style="font-size:18px;"> [[[RACSignal createSignal:</span><span style="font-family: Monaco, Menlo, Consolas, 'Courier New', monospace; white-space: pre-wrap;"><span style="font-size:12px;">^RACDisposable *(id<RACSubscriber> subscriber</span></span><span style="font-size:18px;">) {
NSLog(@"等等我,我还有6秒钟就到了");
[subscriber sendNext:nil];
[subscriber sendCompleted];
return nil;
}] delay:6] subscribeNext:^(id x) {
NSLog(@"我到了");
}];</span>
定时:8小时之后执行一次
[[RACSignal interval:60*60*8 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x) {
NSLog(@"我觉得你该喝水呢!");
}];
[[[RACSignal createSignal:^RACDisposable *(idsubscriber) {
[[[RACSignal createSignal:^RACDisposable *(idsubscriber) {
NSLog(@"我快到了,在等十分钟");
[subscriber sendNext:nil];
[subscriber sendCompleted];
return nil;
}] delay:60*10] subscribeNext:^(id x) {
NSLog(@"不好意思,让你久等了,超了两分钟");
[subscriber sendNext:nil];
[subscriber sendCompleted];
}];
return nil;
}] timeout:60*8 onScheduler:[RACScheduler mainThreadScheduler]] subscribeError:^(NSError *error) {
NSLog(@"等了你八分钟了,你还没来,我走了");
}];
RACCommand *aCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
return [RACSignal createSignal:^RACDisposable *(idsubscriber) {
NSLog(@"我投降了");
[subscriber sendCompleted];
return nil;
}];
}];
[aCommand execute:nil];//执行命令
过滤:
[[[RACSignal createSignal:^RACDisposable *(idsubscriber) {
[subscriber sendNext:@(17)];
[subscriber sendNext:@(21)];
[subscriber sendNext:@(14)];
[subscriber sendNext:@(30)];
return nil;
}] filter:^BOOL(NSNumber* value) {
return value.integerValue >= 18;
}] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
通知:
[[NSNotificationCenter defaultCenter] postNotificationName:@"这是我的代码" object:nil userInfo:@{@"代码":@"用心写"}];
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"这是我的代码" object:nil] subscribeNext:^(NSNotification* x) {
NSLog(@"代码:%@", x.userInfo[@"代码"]);
}];
二:RACCommand:处理事件的类,可以方便的监听事件处理过程
使用场景:网络请求
三步走:
1.创建命令 initWithSignalBlock:(RACSignal * (^)(id input))signalBlock
2.在signalBlock中,创建RACSignal,并且作为signalBlock的返回值
3.执行命令 - (RACSignal *)execute:(id)input
使用:
// 1.创建命令
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
NSLog(@"执行命令");
// 2.创建信号,用来传递数据
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//这里就是网络请求得到的数据
[subscriber sendNext:@"请求数据"];
// 注意:数据传递完,最好调用sendCompleted,这时命令才执行完毕。
[subscriber sendCompleted];
return nil;
}];
}];
// 强引用命令,不要被销毁,否则接收不到数据
_conmmand = command;
// 3.订阅RACCommand中的信号
[command.executionSignals subscribeNext:^(id x) {
[x subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
}];
// RAC高级用法
// switchToLatest:用于signal of signals,获取signal of signals发出的最新信号,也就是可以直接拿到RACCommand中的信号
[command.executionSignals.switchToLatest subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 4.监听命令是否执行完毕,默认会来一次,可以直接跳过,skip表示跳过第一次信号。
[[command.executing skip:1] subscribeNext:^(id x) {
if ([x boolValue] == YES) {
// 正在执行
NSLog(@"正在执行");
}else{
// 执行完成
NSLog(@"执行完成");
}
}];
// 5.执行命令
[self.conmmand execute:@1];
RAC开发中常见用法。
1 代替代理:
rac_signalForSelector
:用于替代代理。
2 代替KVO :
rac_valuesAndChangesForKeyPath
:用于监听某个对象的属性改变。
3 监听事件:
rac_signalForControlEvents
:用于监听某个事件。
4 代替通知:
rac_addObserverForName
:用于监听某个通知。
5 监听文本框文字改变:
rac_textSignal
:只要文本框发出改变就会发出这个信号。