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

作者: Link913 | 来源:发表于2016-08-19 18:01 被阅读1013次

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

    相关文章

      网友评论

      • pengmengli:这是有一个代理方法,如果有两个代理方法,怎么用RACSubject,
        nickNameDC:可以创建多个delagetaSubject,也可以判断出代理方法,要执行哪个,返回什么值。

      本文标题:iOS开发RAC学习笔记(二)RACSubject

      本文链接:https://www.haomeiwen.com/subject/toibsttx.html