iOS開發RAC學習筆記(二)RACSubject

github源代碼地址

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];
      }
    
  • 未完待續

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容