美文网首页
RACSignal信号订阅流程的简单理解

RACSignal信号订阅流程的简单理解

作者: DestinyFighter_ | 来源:发表于2019-04-02 12:02 被阅读0次

    1.信号的使用

    RACSignal* signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
    
         [subscriber sendNext:@"message"];
         return nil;
    }];
    
    [signal subscribeNext:^(id _Nullable x) {
    
         NSLog(@"received:%@", x);
    }];
    

    // 控制台输出: received:message

    2.具体流程如下:

    (1)创建信号:创建 signal 信号对象的时候,最终创建的是 RACSignal 的子类 RACDynamicSignal 的对象,并传入一个名为 didSubscribe,参数为 subscriber 订阅者对象,返回值为 RACDisposable 对象的 block回调,保存到 signal 对象中;(此时信号为冷信号)

    ===== RACDynamicSignal.h =====
    @property (nonatomic, copy, readonly) RACDisposable * (^didSubscribe)(id<RACSubscriber> subscriber);
    
    ===== RACSignal.m =====
    + (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
    
          return [RACDynamicSignal createSignal:didSubscribe];
    }
    
    ===== RACDynamicSignal.m =====
    
    + (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
    
         RACDynamicSignal *signal = [[self alloc] init];
         signal->_didSubscribe = [didSubscribe copy];
    
         return [signal setNameWithFormat:@"+createSignal:"];
    }
    

    (2)订阅信号:订阅者订阅信号的时候,需要调用 signal 对象的 subscribeNext: 方法,此方法会创建一个订阅者对象 subscriber,并传入一个名为 nextBlock,参数为 id 类型, 返回值为 RACDisposable 对象的 block回调,保存到subscriber 对象中;
    然后调用 signal 对象的订阅方法 subscribe: ,参数为前面的 subscriber 对象,返回值为 RACDisposable 对象,此方法中会调用 signal 对象中保存的 didSubscribe 回调;(订阅后信号变为热信号)

    ===== RACSubscriber.m =====
    @property (nonatomic, copy) void (^next)(id value);
    
    ===== RACSignal.m =====
    - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
    
         NSCParameterAssert(nextBlock != NULL);
         RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
    
         return [self subscribe:o];
    }
    
    ===== RACDynamicSignal.m =====
    
    - (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
    
         NSCParameterAssert(subscriber != nil);
         RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
    
         subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
         if (self.didSubscribe != NULL) {
    
             RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
                 RACDisposable *innerDisposable = self.didSubscribe(subscriber);
                 [disposable addDisposable:innerDisposable];
             }];
             [disposable addDisposable:schedulingDisposable];
         }
         return disposable;
    }
    

    (3)发送信号:didSubscribe block 实现中会调用 subscriber 的 sendNext: 方法,发送消息给信号对象,表示订阅者已经订阅信号,sendNext: 方法会同步取出订阅者对象中保存的 nextBlock 并执行,此时信号订阅流程结束。

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

    流程如下图:

    RACSignal.png

    另外,前面创建订阅者时,传入了三个参数,nextBlock,error,completed;创建信号的时候,在网络请求失败的回调中,我们要[subscriber sendError:netError],也就是发送错误信息,然后再订阅错误事件,也就是调用 subscriberError: 方法,这样就完成了错误信息的订阅。

    completed 事件比较特殊,它有终止订阅关系的意味,先大致了解一下RACDispoable对象,我们知道,订阅关系需要有终止的时候,比如,在tableViewCell的复用的时候,cell会订阅model类产生一个信号,但是当cell被复用的时候,如果不把之前的订阅关系取消掉,就会出现同时订阅了2个model的情况。我们可以发现 subscribeNext、subscribeError、subscribeCompleted 事件返回的都是 RACDisopable 对象,当我们希望终止订阅的时候,调用[RACDisposable dispose]就可以了。completed 也是这个原理。

    相关文章

      网友评论

          本文标题:RACSignal信号订阅流程的简单理解

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