iOS开发RAC学习笔记(二)RACSubject
2016-08-19 本文已影响1013人
Link913
RACSubject
RACSubject与RACSignal在发送信号这件事上是基本相同的,用法也是差不多相同的,不同点是RACSubject需要先订阅,然后再发送信号,控制器才能够处理信号,RACReplaySubject则不用考虑订阅信号的先后顺序,所以比较推荐使用这个.另外RACSubject也可以用作代理代理,当然这也是有限制的,只能替代那些没有返回值的代理.
RACSubject的使用
与RACSignal类似,我们先要订阅信号,在发送信号,否则会导致信号无法执行,读取信号的时候可以通过懒加载进行读取
-
控制器接收信号部分
PersonViewModel * viewModel = [[PersonViewModel alloc]init]; //这是错误做法,先发送信号再订阅信号的话对于RACSubject来说的话是不可以的,RACReplaySubject可以先发送信号再去订阅 // [viewModel loadInfo]; //先获取到RACSubject,再订阅他,和RACSignal基本相同的方式 [[viewModel getSubject] subscribeNext:^(id x) { NSLog(@"%@",x); } error:^(NSError *error) { NSLog(@"%@",error); } completed:^{ NSLog(@"完成"); }]; //发送信号 [viewModel loadInfo];
-
viewModel发送信号部分
BOOL isError = NO; if (isError) { [self.subject sendError:[NSError errorWithDomain:@"github.com/SkyHarute" code:2333 userInfo:@{@"errorMessage":@"异常错误"}]]; }else{ [self creatInfo]; [self.subject sendNext:_dataArray]; } [self.subject sendCompleted];
RACReplaySubject的使用
与RACSubject不同,RACReplaySubject在使用时不用过多的考虑订阅与信号发送先后的问题
-
控制器端
AppleViewModel * viewModel = [[AppleViewModel alloc]init]; //这里可以不用考虑是先订阅还是先发送信号的问题 [[viewModel loadInfo] subscribeNext:^(id x) { NSLog(@"%@",x); } error:^(NSError *error) { NSLog(@"%@",error); } completed:^{ NSLog(@"完成"); }];
-
viewModel端与RACSubject相似
RACSubject作为代理
RACSubject作为代理有些局限性,代理方法不能有返回值
-
系统的代理,这里举例一个UIAlertView的代理
[[self rac_signalForSelector:@selector(alertView:clickedButtonAtIndex:) fromProtocol:@protocol(UIAlertViewDelegate)] subscribeNext:^(RACTuple * x) { NSLog(@"%@",x); }];
-
自己写的一个代理,在push之前的控制器执行这段代码
DelegateSecondVC * vc = [[DelegateSecondVC alloc] init]; RACSubject * subject = [RACSubject subject]; //将即将跳转的控制器对其RACSubject属性进行赋值,如果跳转页要让他的代理来做什么只需要发送响应的信号就可以了 vc.delagetaSubject = subject; //这里有个原则,那就是还是要先订阅在发送信号 [subject subscribeNext:^(id x) { NSLog(@"%@",x); } error:^(NSError *error) { NSLog(@"%@",error); } completed:^{ NSLog(@"完成"); }]; [self.navigationController pushViewController:vc animated:YES];
-
在push的第二个页面执行这段代码,就可以了,self.delagetaSubject是暴露在头文件的一个属性,需要第一个控制器来提供,详情请参考demo
if (self.delagetaSubject) { [self.delagetaSubject sendNext:@"haha"]; //若想要持续代理必须注释掉这一步 [self.delagetaSubject sendCompleted]; }
-
未完待续