skip 跳过几个信号,不接受
filter :过滤
ignore:忽略某一个值
take:从开始一共取N次的信号
ignoreValues 这个比较极端,忽略所有值,只关心Signal结束,也就是只取Comletion和Error两个消息,中间所有值都丢弃
takeUntilBlock 对于每个next值,运行block,当block返回YES时停止取值
takeLast 取最后N次的信号,前提条件,订阅者必须调用完成,因为只有完成,就知道总共有多少信号
skipUntilBlock 同理,一直跳,直到block为YES
skipWhileBlock 一直跳,直到block为NO
1.信号量
_curTag=@"error"; @weakify(self) //完整的创建RACSignal 包含三部分sendError(不一定要有) sendNext(可多个) sendCompleted(不一定要有) //RACSubscriber:表示订阅者的意思,用于发送信号,这是一个协议,不是一个类,只要遵守这个协议,并且实现方法才能成为订阅者。通过create创建的信号,都有一个订阅者,帮助他发送数据 RACSignal *signal=[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { @strongify(self) NSError *error; if ([self.curTag isEqualToString:@"error1"]) { error=[[NSError alloc]initWithDomain:@"myError" code:2001 userInfo:nil]; [subscriber sendError:error]; } else { [subscriber sendNext:@"1"]; [subscriber sendNext:@"3"]; [subscriber sendNext:@"5"]; [subscriber sendCompleted]; } return [RACDisposable disposableWithBlock:^{ NSLog(@"执行清理"); //RACDisposable:用于取消订阅或者清理资源,当信号发送完成或者发送错误的时候,就会自动触发它 //使用场景:不想监听某个信号时,可以通过它主动取消订阅信号 }]; }]; [signal subscribeNext:^(id x) { NSLog(@"当前的值为:%@",x); }]; [signal subscribeError:^(NSError *error) { NSLog(@"当前出现错误%@",error); }]; [signal subscribeNext:^(id x) { NSLog(@"2当前的值为:%@",x); }]; //输出 // 执行清理 // 当前出现错误Error Domain=myError Code=2001 "(null)" // 执行清理 // 执行清理
//创建信号 RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { //发送信号 [subscriber sendNext:@"我是好人"]; [subscriber sendCompleted]; return nil; }]; //订阅信号 [signal subscribeNext:^(id x) { NSLog(@"%@",x); }];
上面的代码合成:
//创建信号 [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { //发送信号 [subscriber sendNext:@"我是好人"]; [subscriber sendCompleted]; return nil; }] subscribeNext:^(id x) { NSLog(@"%@",x); }];
运行结果
2.数组字典使用:
NSArray *array = @[@1,@2,@3]; [array.rac_sequence.signal subscribeNext:^(id x) { //1 //2 //3 NSLog(@"%@",x); }];
NSDictionary *dict = @{@"name":@"张三",@"age":@"20",@"sex":@"男"}; [dict.rac_sequence.signal subscribeNext:^(id x) { // 解包元组,会把元组的值,按顺序给参数里面的变量赋值 // RACTupleUnpack这是个宏,后面会介绍 // name---张三 // age---20 // sex---男 RACTupleUnpack(NSString *key,NSString *value) = x; NSLog(@"%@---%@",key,value); //相当与 // NSString *key = x[0]; // NSString *value = x[1]; }];
//把NSArray通过rac_sequence方法生成RAC中的Sequence 获取该Sequence对象的信号量 RACSequence *sequence = [@[@"you", @"are", @"beautiful"] rac_sequence]; //调用Signal的Map方法,使每个元素的首字母大写 RACSignal *signal = sequence.signal; RACSignal *capitalizedSignal = [signal map:^id(NSString * value) { return [value capitalizedString]; }]; // 通过subscribNext方法对其进行遍历输出 [signal subscribeNext:^(NSString * x) { NSLog(@"signal --- %@", x); }]; [capitalizedSignal subscribeNext:^(NSString * x) { NSLog(@"capitalizedSignal --- %@", x); }];
运行结果:
合并信号:
RACSubject *letters = [RACSubject subject]; RACSubject *numbers = [RACSubject subject]; RACSubject *chinese = [RACSubject subject]; [[RACSignal merge:@[letters, numbers, chinese]] subscribeNext:^(id x) { NSLog(@"merge:%@", x); }]; [letters sendNext:@"AAA"]; [numbers sendNext:@"666"]; [chinese sendNext:@"你好!"]; //AAA 666 你好!
组合信号:
RACSubject *letters = [RACSubject subject]; RACSubject *numbers = [RACSubject subject]; [[RACSignal combineLatest:@[letters, numbers] reduce:^(NSString *letter, NSString *number){ // reduce块中是合并规则:把numbers中的值拼接到letters信号量中的值后边。 return [letter stringByAppendingString:number]; }] subscribeNext:^(NSString * x) { NSLog(@"%@", x); }]; [letters sendNext:@"A"]; [letters sendNext:@"B"]; [numbers sendNext:@"1"]; [letters sendNext:@"C"]; [numbers sendNext:@"2"]; //B1 C1 C2
信号开关:
//创建3个自定义信号 RACSubject *google = [RACSubject subject]; RACSubject *baidu = [RACSubject subject]; RACSubject *signalOfSignal = [RACSubject subject]; //获取开关信号 RACSignal *switchSignal = [signalOfSignal switchToLatest]; //对通过开关的信号量进行操作 [[switchSignal map:^id(NSString * value) { return [@"https//www." stringByAppendingFormat:@"%@", value]; }] subscribeNext:^(NSString * x) { NSLog(@"%@", x); }]; //通过开关打开baidu [signalOfSignal sendNext:baidu]; [baidu sendNext:@"baidu.com"]; [google sendNext:@"google.com"]; //通过开关打开google [signalOfSignal sendNext:google]; [baidu sendNext:@"baidu.com/"]; [google sendNext:@"google.com/"];
代理:
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"RAC" message:@"RAC TEST" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"other", nil]; [[self rac_signalForSelector:@selector(alertView:clickedButtonAtIndex:) fromProtocol:@protocol(UIAlertViewDelegate)] subscribeNext:^(RACTuple *tuple) { NSLog(@"%@",tuple.first); NSLog(@"%@",tuple.second); NSLog(@"%@",tuple.third); }]; [alertView show];
字符串信号判断:
_input1 = @"2w435768"; [[RACObserve(self, input1) filter:^(NSString* value){ if ([value hasPrefix:@"2"]) { return YES; } else { return NO; } }] subscribeNext:^(NSString* x){ NSLog(@"%@",x); }];
监听textfield:
[[self.input.rac_textSignal filter:^(NSString *str) { if ([str hasPrefix:@"3545"]) { return YES; } else { return NO; } }] subscribeNext:^(NSString *str) { NSLog(@"%@",str); }];
Button是否可用:
self.isConnected = [NSNumber numberWithBool:true]; RAC(self.loginBtn,enabled) = [RACSignal combineLatest:@[self.name.rac_textSignal, self.password.rac_textSignal, RACObserve(self, isConnected) ] reduce:^(NSString *price, NSString *name, NSNumber *connect){ return @(price.length > 0 && name.length > 0 && [connect boolValue]); } ];
满足条件发送:
[[RACSignal combineLatest:@[self.price.rac_textSignal, self.name.rac_textSignal, RACObserve(self, isConnected) ] reduce:^(NSString *price, NSString *name, NSNumber *connect){ return @(price.length > 0 && name.length > 0 && ![connect boolValue]); }] subscribeNext:^(NSNumber *res){ if ([res boolValue]) { NSLog(@"XXXXX send request"); } }];
RACCommand使用
/** // 1.signalBlock必须要返回一个信号,不能传nil. // 2.如果不想要传递信号,直接创建空的信号[RACSignal empty]; // 3.RACCommand中信号如果数据传递完,必须调用[subscriber sendCompleted],这时命令才会执行完毕,否则永远处于执行中。 // 三、RACCommand设计思想:内部signalBlock为什么要返回一个信号,这个信号有什么用。 // 1.在RAC开发中,通常会把网络请求封装到RACCommand,直接执行某个RACCommand就能发送请求。 // 2.当RACCommand内部请求到数据的时候,需要把请求的数据传递给外界,这时候就需要通过signalBlock返回的信号传递了。 // 四、如何拿到RACCommand中返回信号发出的数据。 // 1.RACCommand有个执行信号源executionSignals,这个是signal of signals(信号的信号),意思是信号发出的数据是信号,不是普通的类型。 // 2.订阅executionSignals就能拿到RACCommand中返回的信号,然后订阅signalBlock返回的信号,就能获取发出的值。 */ //1创建命令 RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) { //命令内部传递的参数 NSLog(@"input===%@",input); //2.返回一个信号,可以返回一个空信号 [RACSignal empty]; return [RACSignal createSignal:^RACDisposable *(id subscriber) { NSLog(@"发送数据"); //发送信号 [subscriber sendNext:@"22"]; // 注意:数据传递完,最好调用sendCompleted,这时命令才执行完毕。 [subscriber sendCompleted]; return nil; }]; }]; //强引用 __command = command; // 拿到返回信号方式二: // command.executionSignals信号中的信号 switchToLatest转化为信号 [command.executionSignals.switchToLatest subscribeNext:^(id x) { NSLog(@"拿到信号的方式二%@",x); }]; //拿到返回信号方式一: RACSignal *signal = [command execute:@"11"]; [signal subscribeNext:^(id x) { NSLog(@"拿到信号的方式一%@",x); }]; //3.执行命令 [command execute:@"11"]; //监听命令是否执行完毕 [command.executing subscribeNext:^(id x) { if ([x boolValue] == YES) { NSLog(@"命令正在执行"); } else { NSLog(@"命令完成/没有执行"); } }]; // input===11 // 命令完成/没有执行 // 命令正在执行 // 发送数据 // 拿到信号的方式一22 // 拿到信号的方式二22 // 令完成/没有执行
通知:
首先,在某个页面中我们需要发出通知,这里就是最基本的通知的写法。发送名为postdata的通知并传送一个数组dataArray。 NSMutableArray *dataArray = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", nil]; [[NSNotificationCenter defaultCenter] postNotificationName:@"postData" object:dataArray]; 而在接受的页面我们需要增加观察者并接受数组,这时我们的RAC就派上用场了。 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"postData" object:nil] subscribeNext:^(NSNotification *notification) { NSLog(@"%@", notification.name); NSLog(@"%@", notification.object); }];
kvo:
UIScrollView *scrolView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 200, 400)]; scrolView.contentSize = CGSizeMake(200, 800); scrolView.backgroundColor = [UIColor greenColor]; [self.view addSubview:scrolView]; [RACObserve(scrolView, contentOffset) subscribeNext:^(id x) { NSLog(@"success"); }];