ReactiveCocoa学习篇——【上】
转载:http://www.jianshu.com/p/53eec1a2ad93 1.ReactiveCocoa是什么? 2.ReactiveCocoa有什么用? 其实这些事件,都可以通过RAC处理,ReactiveCocoa为事件提供了很多处理方法,而且利用RAC处理事件很方便,可以把要处理的事情,和监听的事情的代码放在一起,这样非常方便我们管理,就不需要跳到对应的方法里。非常符合我们开发中 3.已知的编程思想都有哪些?
4.如何导入ReactiveCocoa框架?
5.ReactiveCocoa常见类有哪些?
操作步骤:
// 1.创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// block什么时候调用:当信号被订阅的时候就会调用
// block作用:在这里面传递数据出去
// 3.发送数据
[subscriber sendNext:@1];
return nil;
}];
// 2.订阅信号
// x:信号传递出来的数据
[signal subscribeNext:^(id x) {
// block什么时候调用:当信号内部,发送数据的时候,就会调用,并且会把值传递给你
// block作用:在这个block中处理数据
NSLog(@"%@",x);
}];
RACSignal:表示有数据传递的时候 /*
执行流程:
1.创建信号RACDynamicSignal
* 1.1 把didSubscribe保存到RACDynamicSignal
2.订阅信号
* 2.1 创建订阅者,把nextBlock保存到订阅者里面去
* 2 就会调用信号的didSubscribe
3.执行didSubscribe
* 3.1 拿到订阅者发送订阅者
* [subscriber sendNext:@1]内部就是拿到订阅者的nextBlock
* 信号被订阅,就会执行创建信号时didSubscribe
* 订阅者发送信号,就是调用nextBlock
*/
// 只要订阅者一直在,表示需要一直订阅信号,信号不会自动被取消订阅
// 1.创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
_subscriber = subscriber;
// 3.发送信号
[subscriber sendNext:@1];
return [RACDisposable disposableWithBlock:^{
// 当信号取消订阅的时候就会调用
NSLog(@"信号被取消订阅");
}];
}];
// 2.订阅信号
RACDisposable *disposable = [signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 取消订阅(主动取消)
[disposable dispose];
}
// 1.创建信号
RACSubject *subject = [RACSubject subject];
// 2.订阅信号
[subject subscribeNext:^(id x) {
@"订阅者一%@",x);
}];
[subject subscribeNext:^(@"订阅者二%@",x);
}];
// 3.发送信号
[subject sendNext:@1];
/*
执行流程:
1.创建信号
2.订阅信号
* 创建订阅者
* [self subscribe:o]订阅信号,仅仅是把订阅者保存起来.
3.发送信号
* 把所有的订阅者遍历出来,一个一个的调用它们nextBlock
*/
允许先发送信号,在订阅信号 重复信号提供者 // 1.创建信号 RACReplaySubject *subject = [RACReplaySubject subject]; // 2.发送信号 [subject sendNext:@"123123"]; [subject "345"]; [subject "456456"]; // 1.把值保存到数组 // 2.遍历所有的订阅者,调用nextBlock // 3.订阅信号 [subject subscribeNext:^(id x) { NSLog(@"订阅者一%@",x); }]; // 1.遍历所有值,拿到订阅者去发送 [subject "订阅者二%@",x); }]; /* 执行流程: 1.创建信号 2.订阅信号 * 创建订阅者,保存nextBlock保存 * 遍历valuesReceived需要发送的所有值,拿到一个一个值,利用订阅者发送数据 3.发送信号 * 把发送的值,保存到数组 * 把所有的订阅者遍历出来,一个一个的调用它们nextBlock */
用于当一个信号,被多次订阅时,为了保证创建信号时,避免多次调用创建信号中的block,造成副作用,可以使用这个类处理 简单使用 id<RACSubscriber> subscriber) {
@"发送请求");
// 3.发送信号
[subscriber sendNext:@"网络数据"];
// 2.把信号转换成连接类
RACMulticastConnection *connect = [signal publish];
// 3.订阅连接类的信号,注意:一定是订阅连接类的信号,不再是源信号
[connect.signal subscribeNext:^(// 4.连接
[connect connect];
一个信号即使被订阅多次,也只是发送一次请求RACMulticastConnection:用于信号中请求数据,避免多次请求数据 /*
执行流程
1.创建信号
* 创建RACDynamicSignal,并且把didSubscribe保存到
2.把信号转换成连接类
* 创建信号提供者RACSubject
* [self multicast:subject]:设置原始信号的多点传播subject,本质就是把subject设置为原始信号的订阅者
* 创建RACMulticastConnection,把原始信号保存到_sourceSignal,把subject保存到_signal
3.保存订阅者
4.连接 [connect connect]
* 订阅_sourceSignal,并且设置订阅者为subject
5.执行didSubscribe
6.[subject sendNext]遍历所有的订阅者发送信号
*/
RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,它可以很方便的监控事件的执行过程
// 1.创建命令
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
// signalBlock调用时刻:只要命令一执行就会调用
// signalBlock作用:处理事件
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
@"didSubscribe");
// didSubscribe调用时刻:执行命令过程中,就会调用
// didSubscribe作用:传递数据
// subscriber -> [RACReplaySubject subject]
// RACReplaySubject:把值保存起来,遍历所有的订阅者发送这个值
[subscriber sendNext:@1];
return nil;
}];
}];
// 2.执行命令
RACReplaySubject *replaySubject = (RACReplaySubject *)[command execute:@"执行命令"];
// 3.获取命令中产生的数据,订阅信号
[replaySubject subscribeNext:^(// 1.创建订阅者,订阅信号
// 2.遍历所有值,拿到订阅者去发送
/*
执行流程:
// 1.创建命令
* 把signalBlock保存到命令中
// 2.执行命令
* 调用命令signalBlock
* 创建多点传播连接类,订阅源信号,并且设置源信号的订阅者为RACReplaySubject
* 返回源信号的订阅者
*/
switchToLatest用法 // 1.创建了一个信号中的信号,只能发送信号
RACSubject *signalOfSignals = [RACSubject subject];
// 创建信号,发送普通数据
RACSubject *signalA = [RACSubject subject];
RACSubject *signalB = [RACSubject subject];
// 2.通过订阅信号中信号,拿到signal发出值
// 获取信号中的信号发送最新信号
[signalOfSignals.switchToLatest // 3.发送信号
// 信号中的信号发送数据
[signalOfSignals sendNext:signalA];
[signalOfSignals sendNext:signalB];
// 信号发送数据
[signalB "发送普通数据"];
// 1.命令执行的时候调用
@"执行SignalBlock");
// 处理事情,网络请求
id<RACSubscriber> subscriber) {
// 2.执行完SignalBlock,接着就会调用
@"执行didSubscribe");
// 传送数据,也只会来一次
[subscriber sendNext:@"请求到网络数据"];
// 一定要做事情,声明数据传递完成
// 当数据传递完成,命令就执行完成
[subscriber sendCompleted];
// 直接获取命令中新发出信号
// switchToLatest:只能用于signalOfSignals
// 作用:就是拿到signalOfSignals发出的最新信号
[command.executionSignals.switchToLatest subscribeNext:^(// 订阅当前命令执行状态的信号,正在执行,没有执行
[command.executing subscribeNext:^(id x) {
// x:YES 正在执行
// x:No 没有执行/执行完成
if ([x boolValue] == YES) {
@"正在执行");
}else{
@"没有执行/执行完成");
}
}];
// 2.执行命令
RACSignal *signal = [command execute:@1];
6.ReactiveCocoa常用集合类?
RACTuple: 元组类,类似NSArray,用来包装值.RACSequence: RAC中的集合类,用于代替NSArray,NSDictionary,可以使用它来快速遍历数组和字典 简单使用 RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:@[@"1",@1,22)">@3,22)">@5]];
NSString *str = tuple[0];
OC->RAC NSArray *arr = @[@"123",@1,152)">3,152)">5];
// OC数组转换成RAC集合
RACSequence *sequence = arr.rac_sequence;
// 把集合转换成signal
RACSignal *signal = sequence.signal;
// 订阅集合类的信号,只要订阅这个信号,就会遍历集合中所有元素
[signal subscribeNext:^(id x) {
宏的使用
字典转模型 // RAC:集合,相当于数组或者字典
// 这个类的创建必须要依赖于数组或者字典
// 解析plist
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil];
NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];
_flags = [NSMutableArray array];
[dictArr.rac_sequence.signal subscribeNext:^(NSDictionary *x) {
Flag *flag = [Flag flagWithDict:x];
[_flags addObject:flag];
}];
方式二: NSMutableArray array];
_flags = [[dictArr.rac_sequence map:^id(id value) {
// value:就是原始信号发送的值,字典
// block返回值就是需要映射的对象
return [Flag flagWithDict:value];
}] array];(编辑:李大同)
|