RACSubject
RACSubject與RACSignal在發(fā)送信號這件事上是基本相同的,用法也是差不多相同的,不同點(diǎn)是RACSubject需要先訂閱,然后再發(fā)送信號,控制器才能夠處理信號,RACReplaySubject則不用考慮訂閱信號的先后順序,所以比較推薦使用這個.另外RACSubject也可以用作代理代理,當(dāng)然這也是有限制的,只能替代那些沒有返回值的代理.
RACSubject的使用
與RACSignal類似,我們先要訂閱信號,在發(fā)送信號,否則會導(dǎo)致信號無法執(zhí)行,讀取信號的時候可以通過懶加載進(jìn)行讀取
-
控制器接收信號部分
PersonViewModel * viewModel = [[PersonViewModel alloc]init]; //這是錯誤做法,先發(fā)送信號再訂閱信號的話對于RACSubject來說的話是不可以的,RACReplaySubject可以先發(fā)送信號再去訂閱 // [viewModel loadInfo]; //先獲取到RACSubject,再訂閱他,和RACSignal基本相同的方式 [[viewModel getSubject] subscribeNext:^(id x) { NSLog(@"%@",x); } error:^(NSError *error) { NSLog(@"%@",error); } completed:^{ NSLog(@"完成"); }]; //發(fā)送信號 [viewModel loadInfo];
-
viewModel發(fā)送信號部分
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在使用時不用過多的考慮訂閱與信號發(fā)送先后的問題
-
控制器端
AppleViewModel * viewModel = [[AppleViewModel alloc]init]; //這里可以不用考慮是先訂閱還是先發(fā)送信號的問題 [[viewModel loadInfo] subscribeNext:^(id x) { NSLog(@"%@",x); } error:^(NSError *error) { NSLog(@"%@",error); } completed:^{ NSLog(@"完成"); }];
viewModel端與RACSubject相似
RACSubject作為代理
RACSubject作為代理有些局限性,代理方法不能有返回值
-
系統(tǒng)的代理,這里舉例一個UIAlertView的代理
[[self rac_signalForSelector:@selector(alertView:clickedButtonAtIndex:) fromProtocol:@protocol(UIAlertViewDelegate)] subscribeNext:^(RACTuple * x) { NSLog(@"%@",x); }];
-
自己寫的一個代理,在push之前的控制器執(zhí)行這段代碼
DelegateSecondVC * vc = [[DelegateSecondVC alloc] init]; RACSubject * subject = [RACSubject subject]; //將即將跳轉(zhuǎn)的控制器對其RACSubject屬性進(jìn)行賦值,如果跳轉(zhuǎn)頁要讓他的代理來做什么只需要發(fā)送響應(yīng)的信號就可以了 vc.delagetaSubject = subject; //這里有個原則,那就是還是要先訂閱在發(fā)送信號 [subject subscribeNext:^(id x) { NSLog(@"%@",x); } error:^(NSError *error) { NSLog(@"%@",error); } completed:^{ NSLog(@"完成"); }]; [self.navigationController pushViewController:vc animated:YES];
-
在push的第二個頁面執(zhí)行這段代碼,就可以了,self.delagetaSubject是暴露在頭文件的一個屬性,需要第一個控制器來提供,詳情請參考demo
if (self.delagetaSubject) { [self.delagetaSubject sendNext:@"haha"]; //若想要持續(xù)代理必須注釋掉這一步 [self.delagetaSubject sendCompleted]; }
未完待續(xù)