ReactiveCocoa 基本使用回忆录
RACSignal
//Signal 测试
-(void)testRacSignal{
//1 创建信号-默认是冷信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//3 发送数据
NSLog(@"信号被订阅");
[subscriber sendNext:@100];
return nil;
}];
//2.订阅信号
[signal subscribeNext:^(id x) {
NSLog(@"信号发送的内容1 %@",x);
}];
[signal subscribeNext:^(id x) {
NSLog(@"信号发送的内容2 %@",x);
}];
}
//Signal 测试2
-(void)testRacSignal2{
//1 创建信号-默认是冷信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//3 发送数据
NSLog(@"信号被订阅");
self.subscriber = subscriber;
[subscriber sendNext:@100];
return [RACDisposable disposableWithBlock:^{
//只要信号取消订阅就会来这
NSLog(@"信号订阅完成");
}];
}];
//2.订阅信号
RACDisposable *disposable = [signal subscribeNext:^(id x) {
NSLog(@"信号发送的内容 %@",x);
}];
// 1.创建订阅者,保存nextBlock
// 2.订阅信号
// 默认一个信号发送数据完毕们就会主动取消订阅.
// 只要订阅者在,就不会自动取消信号订阅
// 取消订阅信号
[disposable dispose];
}
RACSubject
信号提供者,自己可以充当信号,又能发送信号
-(void)RACSubject{
//1.创建信号
RACSubject *subject = [RACSubject subject];
//2.订阅信号
[subject subscribeNext:^(id x) {
NSLog(@"接收到数据:%@",x);
}];
//3.发送数据
[subject sendNext:@100];
}
RACReplaySubject
RACReplaySubject:可以先发送信号,在订阅信号,RACSubject就不可以。
-(void)RACReplaySubject{
RACReplaySubject *subject = [RACReplaySubject subject];
[subject subscribeNext:^(id x) {
NSLog(@"接收到数据:%@",x);
}];
[subject sendNext:@"LouKit"];
}
RACMulticastConnection
用于当一个信号,被多次订阅时,为了保证创建信号时,避免多次调用创建信号中的block,造成副作用,可以使用这个类处理
-(void)RACMulticastConnection{
// 1.创建信号
// 2.把信号转换成连接类
// 3.订阅连接类的信号
// 4.连接
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"信号被订阅");
[subscriber sendNext:@100];
return nil;
}];
//把信号转换成链接类
// 确定源信号的订阅者RACSubject
// RACMulticastConnection *connection = [signal publish];
RACMulticastConnection *connection = [signal multicast:[RACReplaySubject subject]];
//订阅信号,也不能激活信号,只是保存订阅者到数组,必须通过连接,当调用连接,就会一次性调用所有订阅者的sendNext:
[connection.signal subscribeNext:^(id x) {
NSLog(@"订阅者1:%@",x);
}];
[connection.signal subscribeNext:^(id x) {
NSLog(@"订阅者2:%@",x);
}];
// 4.连接,激活信号
[connection connect];
}
RACCommand
RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,可以很方便的监控事件的执行过程。
-(void)RACCommand{
// RACCommand:处理事件
// RACCommand:不能返回一个空的信号
//1.创建命令
RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
// input:执行命令传入参数
// Block调用:执行命令的时候就会调用
NSLog(@"input:%@",input);
// return[RACSignal empty];
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"执行命令产生的数据"];
return nil;
}];
}];
//2 执行命令
RACSignal *signal = [command execute:@1];
//3. 订阅信号
[signal subscribeNext:^(id x) {
NSLog(@"订阅到数据:%@",x);
}];
}
-(void)RACCommand2{
RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"data"];
return nil;
}];
}];
// 订阅信号
// 注意:必须要在执行命令前,订阅
//executionSignals:信号源,信号中信号,signalOfSignals:信号:发送数据就是信号
// [command.executionSignals subscribeNext:^(RACSignal *x) {
// [x subscribeNext:^(id x) {
// NSLog(@"收到的数据:%@",x);
// }];
// }];
// switchToLatest获取最新发送的信号,只能用于信号中信号
[command.executionSignals.switchToLatest subscribeNext:^(id x) {
NSLog(@"收到的数据:%@",x);
}];
[command execute:@1];
}
-(void)RACCommand3{
// 当前命令内部发送数据完成,一定要主动发送完成
// 1.创建命令
RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"data"];
[subscriber sendCompleted];
return nil;
}];
}];
[command.executing subscribeNext:^(id x) {
if ([x boolValue]) {
NSLog(@"当前正在执行");// 当前正在执行
}else{
// 执行完成/没有执行
NSLog(@"执行完成/没有执行");
}
}];
// 2.执行命令
[command execute:@1];
}
RACTuple、RACSequence
//RACTuple:元组类,类似NSArray,用来包装值.
//RACSequence:RAC中的集合类,用于代替NSArray,NSDictionary,可以使用它来快速遍历数组和字典。
-(void)RACTuple{
NSArray *numbers = @[@1,@2,@3,@4];
RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:numbers];
NSLog(@"tuple:%@",tuple[0]);
[numbers.rac_sequence.signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
//字典
NSDictionary *dict = @{@"key1":@"value1",@"key2":@"value2",@"key3":@100};
[dict.rac_sequence.signal subscribeNext:^(RACTuple *tuple) {
// NSString *key = tuple[0];
// NSString *value = tuple[1];
// RACTupleUnpack:用来解析元组
// 宏里面的参数,传需要解析出来的变量名
// = 右边,放需要解析的元组
RACTupleUnpack(NSString *key,NSString *value) = tuple;
NSLog(@"key:%@,vlaue:%@",key,value);
}];
}
bind
[[_textfield.rac_textSignal bind:^RACStreamBindBlock{
return ^RACStream*(id value, BOOL *stop){
return [RACReturnSignal return:[NSString stringWithFormat:@"LK:%@",value]];
};
}]subscribeNext:^(id x) {
self.lable.text = x;
}];
flattenMap
//映射
-(void)flattenMap{
// flattenMap作用:把源信号的内容映射成一个新的信号,信号可以是任意类型。
[[_textfield.rac_textSignal flattenMap:^RACStream *(id value) {
return [RACReturnSignal return:[NSString stringWithFormat:@"LK:%@",value]];
}]subscribeNext:^(id x) {
self.lable.text = x;
}];
}
map
/**
FlatternMap和Map的区别
1.FlatternMap中的Block返回信号。
2.Map中的Block返回对象。
3.开发中,如果信号发出的值不是信号,映射一般使用Map
4.开发中,如果信号发出的值是信号,映射一般使用FlatternMap。
**/
-(void)map{
[[_textfield.rac_textSignal map:^id(id value) {
return [NSString stringWithFormat:@"LL:%@",value];
}]subscribeNext:^(id x) {
self.lable.text = x;
}];
}
signalOfsignals
-(void)signalOfsignals{
RACSubject *signalOfsignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject];
[[signalOfsignals flattenMap:^RACStream *(id value) {
//当signalOfsignals的signals发出信号才会调用
return value;
}]subscribeNext:^(id x) {
NSLog(@"signalOfsignals:%@",x);
}];
[signalOfsignals sendNext:signal];
[signal sendNext:@1];
}
concat
concat:按一定顺序拼接信号,当多个信号发出的时候,有顺序的接收信号。
-(void)concat{
//concat:按一定顺序拼接信号,当多个信号发出的时候,有顺序的接收信号。
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"A100"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"B100"];
[subscriber sendCompleted];
return nil;
}];
// 把signalA拼接到signalB后,signalA发送完成,signalB才会被激活。
RACSignal *signal = [signalA concat:signalB];
//注意:第一个信号必须发送完成,第二个信号才会被激活
[signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
}
then
用于连接两个信号,当第一个信号完成,才会连接then返回的信号。
注意使用then,之前信号的值会被忽略掉.
-(void)then{
//用于连接两个信号,当第一个信号完成,才会连接then返回的信号。
//注意使用then,之前信号的值会被忽略掉.
[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@100];
[subscriber sendCompleted];
return nil;
}]then:^RACSignal *{
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@200];
[subscriber sendCompleted];
return nil;
}];
}]subscribeNext:^(id x) {
NSLog(@"%@",x);//200
}];
}
merge
把多个信号合并为一个信号,任何一个信号有新值的时候就会调用.
-(void)merge{
//把多个信号合并为一个信号,任何一个信号有新值的时候就会调用.
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"A100"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"B100"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signal = [signalA merge:signalB];
[signal subscribeNext:^(id x) {
NSLog(@"%@",x);//200
}];
}
zipWith
把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元组,才会触发压缩流的next事件
-(void)zipWith{
//把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元组,才会触发压缩流的next事件
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"A100"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"B100"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *siganl = [signalA zipWith:signalB];
[siganl subscribeNext:^(id x) {
NSLog(@"%@",x);//包装成元组发出
/**
<RACTuple: 0x608000019fb0> (
A100,
B100
)
**/
}];
}
combineLatest
将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号。
-(void)combineLatest{
//将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号。
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"A100"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"B100"];
[subscriber sendCompleted];
return nil;
}];
//把两个信号组合成一个信号,跟zip一样,没什么区别
RACSignal *siganl = [signalA combineLatestWith:signalB];
[siganl subscribeNext:^(id x) {
NSLog(@"%@",x);//包装成元组发出
/**
<RACTuple: 0x608000019fb0> (
A100,
B100
)
**/
}];
}
reduce
聚合:用于信号发出的内容是元组,把信号发出元组的值聚合成一个值
-(void)reduce{
//聚合:用于信号发出的内容是元组,把信号发出元组的值聚合成一个值
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"A100"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"B100"];
[subscriber sendCompleted];
return nil;
}];
// 常见的用法,(先组合在聚合)。combineLatest:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock
// reduce中的block简介:
// reduceblcok中的参数,有多少信号组合,reduceblcok就有多少参数,每个参数就是之前信号发出的内容
// reduceblcok的返回值:聚合信号之后的内容。
RACSignal *reduceSignal = [RACSignal combineLatest:@[signalA,signalB] reduce:^id(NSNumber *num1 ,NSNumber *num2){
return [NSString stringWithFormat:@"%@ %@",num1,num2];
}];
[reduceSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
}
待续…..