前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >RAC(ReactiveCocoa)介绍(四)——流程分析

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

作者头像
我只不过是出来写写代码
发布2019-04-02 14:59:26
1.1K0
发布2019-04-02 14:59:26
举报

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

代码语言:javascript
复制
    //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

  1. 订阅信号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的核心之一。

代码语言:javascript
复制
            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流程分析简图

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.05.23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档