之前的文章一直在写关于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代码块,
- 创建信号signal 在创建信号signal的方法createSignal中,可以看到是由RACDynamicSignal类创建的信号signal
创建信号方法 方法中可以看出,将block代码块didSubscribe复制copy给了当前的实例变量_didSubscribe
- 订阅信号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流程分析简图