RACSignal:
信号类,当数据改变的时候,内部会发出信号,本身不能发送信号,而是交给一个订阅者(RACSubscriber)去发送,创建的时候block内部会带一个订阅者。
RACSubscriber:
订阅者,本身是个协议,用于发送信号,
RACDisposable:
清洁工,用于取消订阅,或者清理资源,
// 创建信号 RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { //发送信号 [subscriber sendNext:@"发送消息"]; //发送信号完成 [subscriber sendCompleted]; return [RACDisposable disposableWithBlock:^{ NSLog(@"信号被销毁"); }]; }]; // 只有订阅信号才能接收到数据 [signal subscribeNext:^(id x) { NSLog(@"接收到数据:%@",x); }];
RACCommand:
事件的处理类,运用这个类可以监听到事件执行的整个过程
self.command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) { //默认要创建一个信号,如果不做任何操作可以创建空信号 // return [RACSignal empty]; //input这个参数是执行的时候传入的,根据这个参数可以看出RACCommand的运行过程 return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { //发送 [subscriber sendNext:input]; [subscriber sendCompleted]; return nil; }]; }]; //订阅(信号中的信号),switchToLatest:获取信号中的信号,有的时候信号也可以发出信号 [[self.command.executionSignals switchToLatest] subscribeNext:^(id _Nullable input) { NSLog(@"%@",input); }]; //执行 [self.command execute:@(1)];
RACSubject和RACReplaySubject:
RACSubject可以提供信号,自己也是信号的提供者,
RACReplaySubject是RACSubject子类,可以重复提供信号,可以先发送,再订阅,也可以多次订阅,但是RACSubjec由于过于灵活,官方也不建议使用。
RACSubject * subject = [RACSubject subject]; //先订阅 [subject subscribeNext:^(id _Nullable x) { NSLog(@"%@",x); }]; //一定要先订阅再发送 [subject sendNext:@"1"]; RACReplaySubject *replaySubject = [RACReplaySubject subject]; //可以先发送再订阅 [replaySubject sendNext:@"1"]; [replaySubject sendNext:@"2"]; [replaySubject subscribeNext:^(id _Nullable x) { //只要订阅了就会接受到发送的所有数据,所以订阅的block都会执行两次 NSLog(@"%@",x); }]; [replaySubject subscribeNext:^(id _Nullable x) { NSLog(@"%@",x); }];
4.基本用法
基本宏
1.RAC(TARGET, [KEYPATH, [NIL_VALUE]]) 绑定对象属性
2.RACObserve(self, name) 监听属性变化的信号
3.
//RACTuplePack:把数据包装成元祖 RACTuple *tuple = RACTuplePack(@(111),@"222"); //RACTuplePack:解包,把元祖解包成对应的数据类型 RACTupleUnpack(NSNumber * number,NSString * string) = tuple; NSLog(@"%@--%@",number,string); //RACTuple提供了直接访问元素的属性 NSNumber *tNumber = tuple.first; NSString *tString = tuple.second; NSLog(@"%@--%@",tNumber,tString);
替换传统消息机制
- rac_signalForSelector 替换代理
- rac_signalForControlEvents 替换UIControl Target-Action方法
- rac_valuesAndChangesForKeyPath 替换KVO
- rac_addObserverForName 替换通知
- rac_textSignal 替换文本监听代理
rac_signalForSelector替换代理有局限性,只能用于没有返回值的代理
使用基本方法
1.过滤
- filter
[[self.userNameTF.rac_textSignal filter:^BOOL(NSString * value){ //用户登录的时候限制用户名的长度 return value.length > 11; }] subscribeNext:^(id x){ //过滤信号,符合条件订阅才会接收到 NSLog(@"%@", x); }];
- distinctUntilChanged:
也有过滤的功能,当信号中上一次的值与当前的值又变化的时候,就会发出信号。 - take,takeLast,skip
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { [subscriber sendNext:@"1"]; [subscriber sendNext:@"2"]; [subscriber sendNext:@"3"]; [subscriber sendCompleted]; return nil; }]; [[signal take:2] subscribeNext:^(id _Nullable x) { //订阅信号,“2”代表取前两次的信号,打印1,2 NSLog(@"%@",x); }]; [[signal takeLast:2] subscribeNext:^(id x) { //订阅信号,“2”代表取最后两次的信号,打印2,3 NSLog(@"%@",x); }]; [[signal skip:2] subscribeNext:^(id _Nullable x) { //skip代表跳过信号,参数代表个数,跳过两个信号,打印3 NSLog(@"%@",x); }];
2.映射(map&flatternMap)
//flattenMap和map的区别就是返回的是值还是信号 [[self.userNameTF.rac_textSignal map:^id _Nullable(NSString * _Nullable value) { //用户登录限制长度也可以用映射,把用户输入的字符串的信号转化成是否可以登录的信号 return @(value.length > 11); }] subscribeNext:^(NSNumber *_Nullable isLogin) { NSLog(@"%d",[isLogin boolValue]); }]; //当就要映射信号的时候用flattenMap [self.userNameTF.rac_textSignal flattenMap:^__kindof RACSignal * _Nullable(NSString * _Nullable value) { //需要返回信号 return self.userNameTF.rac_textSignal; }];
3.合并
- concat拼接
RACSignal *signle2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { [subscriber sendNext:@"3"]; [subscriber sendNext:@"4"]; [subscriber sendCompleted]; return nil; }]; [[signle1 concat:signle2] subscribeNext:^(id _Nullable x) { //concat拼接功能,把signle1拼到signle2之前,按照顺序执行,打印1,2,3,4 NSLog(@"%@",x); }];
- merge&zip&combineLatest 组合
RACSignal *signle1 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { [subscriber sendNext:@"1"]; [subscriber sendNext:@"2"]; [subscriber sendCompleted]; return nil; }]; RACSignal *signle2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { [subscriber sendNext:@"3"]; [subscriber sendNext:@"4"]; [subscriber sendCompleted]; return nil; }]; [[signle1 merge:signle2] subscribeNext:^(id _Nullable x) { //merge,合并信号,当signle1和signle2任意一个发送,都会接收到,有点类似concat NSLog(@"%@",x); }]; [[signle1 zipWith:signle2] subscribeNext:^(RACTuple *_Nullable tuple) { //zip压缩信号,并把值也合并成元祖,但也是一个一个合并,所以会走两遍,1,3 2,4 NSLog(@"%@--%@",tuple.first,tuple.second); }]; [[signle1 combineLatestWith:signle2] subscribeNext:^(RACTuple * _Nullable tuple) { //combineLatestWith也是合并信号,跟zip有点像,但是sigle1总会拿到最新的值才与signle2合并,打印 2,3 2,4 NSLog(@"%@--%@",tuple.first,tuple.second); }];
- then
RACSignal * signle = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { [subscriber sendNext:@"1"]; [subscriber sendNext:@"2"]; [subscriber sendCompleted]; return nil; }]; [[signle then:^RACSignal * _Nonnull{ return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { [subscriber sendNext:@"3"]; return nil; }]; }] subscribeNext:^(id _Nullable x) { //then会把之前的信号过滤掉,所以这里只会接收到第二个信号的值 3 NSLog(@"%@",x); }]; [signle subscribeNext:^(id _Nullable x) { //第一个信号订阅了,所以顺序执行到这里才会打印1,2 NSLog(@"%@",x); }];
- delay&interval
[[RACSignal interval:5 onScheduler:[RACScheduler currentScheduler]] subscribeNext:^(NSDate * _Nullable x) { //定时,每个一段时间会调用,会把当前时间回调回来 NSLog(@"%@",x); }]; RACSignal *signle = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { [subscriber sendNext:@"1"]; [subscriber sendCompleted]; return nil; }]; [[signle delay:5] subscribeNext:^(id _Nullable x) { //延迟订阅 NSLog(@"%@",x); }
时间: 2024-10-10 05:51:32