iOS RAC初探 RACSignal解析

RACSignal 信号类 信号类本身并不具备发送消息的能力,而是通过subscriber来发送信息的。
RACSignal 创建信号
subscriber 发送信息
RACSignal 通过subscribeNext订阅信号

 //1、
 RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        NSLog(@"创建了一个信号");
        
        //发送信息
        [subscriber sendNext:@"hello world"];

        return [RACDisposable disposableWithBlock:^{
            NSLog(@"销毁了");
        }];
    }];

 //2、订阅信号量
 [signal subscribeNext:^(id  _Nullable x) {
       NSLog(@"%@",x); 
 }];

第一步RACSignal 创建信号

RACSignal创建信号解析(进入RAC源码可见,创建RACSignal信号其实是创建RACDynamicSignal且将本身需要执行的block也一并传递过去了):

+ (RACSignal *)createSignal:(RACDisposable * (^)(id subscriber))didSubscribe {
    return [RACDynamicSignal createSignal:didSubscribe];
}
+ (RACSignal *)createSignal:(RACDisposable * (^)(id subscriber))didSubscribe {
    RACDynamicSignal *signal = [[self alloc] init];
    //从RACSignal中传递过来的didSubscribe
    signal->_didSubscribe = [didSubscribe copy];
    return [signal setNameWithFormat:@"+createSignal:"];
}

第一步创建的流程图如下:


iOS RAC初探 RACSignal解析_第1张图片
屏幕快照 2019-01-14 下午5.47.53.png

那我们什么时候调用到didSubscirbe这个block呢??带着这个疑问往下继续深入探讨后续代码。

第二步订阅信号

既然我们是创建了信号,肯定要订阅它,所以我们要先执行订阅信号的操作解析

 [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"订阅了: %@",x);
 }];

这是订阅信号的操作,具体内容需要进入到RAC源码中:

- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
    NSCParameterAssert(nextBlock != NULL);
    //在订阅的操作中,创建了一个RACSubscriber类(订阅者),并将订阅block传递进去,保存了nextBlock这个block
    RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
   //创建完RACSubscriber后,调用subscribe,这里需要注意的是,因为我们创建的RACDynamicSignal,所以其实这里本质是调用的RACDynamicSignal subscribe:o
    return [self subscribe:o];
}

创建订阅者 并保存了nextBlock

+ (instancetype)subscriberWithNext:(void (^)(id x))next error:(void (^)(NSError *error))error completed:(void (^)(void))completed {
    RACSubscriber *subscriber = [[self alloc] init];

    subscriber->_next = [next copy];
    subscriber->_error = [error copy];
    subscriber->_completed = [completed copy];

    return subscriber;
}

调用RACDynamicSignal subscribe

- (RACDisposable *)subscribe:(id)subscriber {
    NSCParameterAssert(subscriber != nil);
    RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
    subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
    //这里判断didSubcribe是否为空
    if (self.didSubscribe != NULL) {
        //这里就在调用didSubscribe方法,并且把刚才传入的subscriber调用出去
        RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
            //调用创建信号时候的didSubscribe这个block的内容
            RACDisposable *innerDisposable = self.didSubscribe(subscriber);
            [disposable addDisposable:innerDisposable];
        }];

        [disposable addDisposable:schedulingDisposable];
    }
    return disposable;
}

第二步流程图如下:


iOS RAC初探 RACSignal解析_第2张图片
屏幕快照 2019-01-14 下午6.09.22.png

第三步 发送信息调用订阅中的nextBlock块代码

RACSignal 通过subscribeNext订阅信号

 //1、
 RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        NSLog(@"创建了一个信号");
        
        //发送信息
        [subscriber sendNext:@"hello world"];

        return [RACDisposable disposableWithBlock:^{
            NSLog(@"销毁了");
        }];
    }];

 //2、订阅信号量
 [signal subscribeNext:^(id  _Nullable x) {
       NSLog(@"%@",x); 
 }];

通过sendNext 发送信息内容而后调用nextBlock块,具体代码解析:

- (void)sendNext:(id)value {
    @synchronized (self) {
        void (^nextBlock)(id) = [self.next copy];
        if (nextBlock == nil) return;

        nextBlock(value);
    }
}

这里主要就是做了一件事,如果nextblock不为空就把传进来传value原封不动的调用出去。 而这个nextblock就是我们在订阅信号的时候创建的那个subscriber所保存的nextblock。

所以RACSignal的整体处理流程如下

  • 创建信号的block会在订阅信号的时候调用 subscribe
  • 订阅信号的block会在订阅者发布信息的时候调用 sendNext
iOS RAC初探 RACSignal解析_第3张图片
屏幕快照 2019-01-14 下午6.14.33.png

你可能感兴趣的:(iOS RAC初探 RACSignal解析)