热门搜索 :
考研考公
您的当前位置:首页正文

iOS开发RAC学习笔记(二)RACSubject

来源:东饰资讯网

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

Top