美文网首页函数响应式编程raciOS-RAC
RAC(ReactiveCocoa)介绍(四)——流程分析

RAC(ReactiveCocoa)介绍(四)——流程分析

作者: 我只不过是出来写写代码 | 来源:发表于2018-05-23 21:44 被阅读138次

    之前的文章一直在写关于RAC框架中某些方法的实现原理、具体使用作用以及代码实现,基本上也对RAC有了一个初步的认识。这次不打算继续记录关于RAC中具体的方法,准备放到后面慢慢分析,这篇准备继续深入探究一下RAC中信号的流程分析。这样对RAC认识会更加深刻,有助于后续的理解。
    首先,贴上之前的代码为例

        //1. 创建signal信号
        RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            
            //subscriber并不是一个对象
            //3. 发送信号
            [subscriber sendNext:@"send one Message"];
            
            //发送error信号
            NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:1001 userInfo:@{@"errorMsg":@"this is a error message"}];
            [subscriber sendError:error];
            
            //4. 销毁信号
            return [RACDisposable disposableWithBlock:^{
                NSLog(@"signal已销毁");
            }];
        }];
        
        //2.1 订阅信号
        [signal subscribeNext:^(id  _Nullable x) {
            NSLog(@"%@",x);
        }];
        //2.2 针对实际中可能出现的逻辑错误,RAC提供了订阅error信号
        [signal subscribeError:^(NSError * _Nullable error) {
            NSLog(@"%@",error);
        }];
    
    执行打印结果

    按照代码中的执行步骤:
    在创建信号signal之后,订阅了两个信号signal;当分别发送两个信号signal时,订阅信号signal方法block中首先打印出发送信号signal的内容,然后执行信号signal销毁。注意:RAC方法中的block代码块,

    1. 创建信号signal
      在创建信号signal的方法createSignal中,可以看到是由RACDynamicSignal类创建的信号signal


      创建信号方法

      方法中可以看出,将block代码块didSubscribe复制copy给了当前的实例变量_didSubscribe

    2. 订阅信号signal
      订阅信号方法subscribeNext中,使用RACSubscriber类进行了初始化并将next的block保存。在该实例化方法中,也可将error的block与completed的block传入,此处因外部使用subscribeNext方法,所以只传入next。与之相对应的,subscribeError方法则是初始化并保存了error的block,subscribeCompleted方法是初始化并保存了completed的block。


      将订阅信号进行初始化

      订阅信号实现代码中,[self subscribe:o]方法中的self的类是RACDynamicSignal(刚才第1步中创建信号类为RACDynamicSignal),进入RACDynamicSignal类中的subscribe方法。


      RACDynamicSignal类中subscribe实现方法

    RACCompoundDisposable为组合式销毁栈,用于处理信号的销毁。至于其中如何运作的,之后专门用一篇幅来详细介绍。

    subscriber被重新指向由RACPassthroughSubscriber类初始化的对象,通过该类创建的对象才是信号真正的订阅者。通过该方法将信号、订阅者、销毁者全部传入进去,换句话说,就是该方法将信号、订阅者、销毁者进行了关联,从而实现不断订阅、不断销毁。此处亦是RAC的核心之一。

                RACDisposable *innerDisposable = self.didSubscribe(subscriber);
                [disposable addDisposable:innerDisposable];
    

    此处代码要注意到,是执行了self.didSubscribe(id<RACSubscriber> subscriber)代码块。而self.didSubscribe(id<RACSubscriber> subscriber)是在创建信号的时候,进行了copy赋值操作,在订阅者这里进行执行操作。所以,在第2步订阅信号创建的时候,会进入第1步创建信号的block代码块中寻找并执行自定义添加的代码,也就是准备开始执行第一张代码图中的第3步、第4步操作。

    第3步,发送信号signal
    通过进入RACSubscriber类中的sendNext方法查看实现代码


    sendNext方法实现

    保证RACSubscriber类的线程安全,将self.next代码块copy至一个本地代码块,并将其执行。此处的self.next正是在第2步订阅信号过程中,保存的nextBlock代码块。 最终在执行发送信号signal的时候,会查找并执行在第2步订阅信号方法中的block代码块。

    因此,整个信号流程的执行,也正是函数式编程思想的完美体现。

    最后再配上一张流程图,来总结一下上述实现的步骤。


    RAC流程分析简图

    相关文章

      网友评论

      本文标题:RAC(ReactiveCocoa)介绍(四)——流程分析

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