一張圖理解RACSignal的Subscription過程

經過下面一張圖理解RACSignal的調用過程:
RAC閉包

建立signale

RACSignal經過子類[RACDynamicSignal createSignal:]方法得到Signal,並將disSubscribe這個block保存在Signal中。異步

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

建立subscriber

signal經過調用subscribeNext方法生成subscriber,並將next、error、completed block保存在subscriber中code

- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
    NSCParameterAssert(nextBlock != NULL);
    
    RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
    return [self subscribe:o];
}
+ (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;
}

進行subscribe

第二步建立subscriber以後調用signal的subscribe方法,並將建立的subscriber做爲參數。
這一步會生成RACCompoundDisposable和RACPassthroughSubscriber對象。orm

  • RACCompoundDisposable:RACDisposable的子類,能夠加入多個RACDisposable對象。當RACCompoundDisposable對象被dispose的時候,會dispose容器內的全部RACDisposable對象。
  • RACPassthroughSubscriber:分別保存對RACSignal,RACSubscriber,RACCompoundDisposable的引用。經過RACPassthroughSubscriber對象來轉發給真正的Subscriber。
- (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;
}

執行disSubscribe block

RACSignal經過RACScheduler.subscriptionScheduler來執行閉包,disSubscribe真正被調用的的位置就是上一步的RACDisposable *innerDisposable = self.didSubscribe(subscriber);對象

- (RACDisposable *)schedule:(void (^)(void))block {
    NSCParameterAssert(block != NULL);

    if (RACScheduler.currentScheduler == nil) return [self.backgroundScheduler schedule:block];

    block();
    return nil;
}

調用sendNext sendError sendCompleted

進入didSubscribe閉包後,調用sendNext:、sendError:、sendCompleted。因爲第三步中將subscriber替換爲RACPassthroughSubscriber對象,真正的subscriber被存儲在RACPassthroughSubscriber對象中,即innerSubscriber,因此這一步的各類send方法實際上是一個轉發過程。ip

- (void)sendNext:(id)value {
    if (self.disposable.disposed) return;

    if (RACSIGNAL_NEXT_ENABLED()) {
        RACSIGNAL_NEXT(cleanedSignalDescription(self.signal), cleanedDTraceString(self.innerSubscriber.description), cleanedDTraceString([value description]));
    }

    [self.innerSubscriber sendNext:value];
}

- (void)sendError:(NSError *)error {
    if (self.disposable.disposed) return;

    if (RACSIGNAL_ERROR_ENABLED()) {
        RACSIGNAL_ERROR(cleanedSignalDescription(self.signal), cleanedDTraceString(self.innerSubscriber.description), cleanedDTraceString(error.description));
    }

    [self.innerSubscriber sendError:error];
}

- (void)sendCompleted {
    if (self.disposable.disposed) return;

    if (RACSIGNAL_COMPLETED_ENABLED()) {
        RACSIGNAL_COMPLETED(cleanedSignalDescription(self.signal), cleanedDTraceString(self.innerSubscriber.description));
    }

    [self.innerSubscriber sendCompleted];
}

執行next error completed閉包

經過調用innerSubscriber的sendNext:、sendError、和sendCompleted方法執行真正的subscriber中的next error completed閉包it

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

        nextBlock(value);
    }
}

- (void)sendError:(NSError *)e {
    @synchronized (self) {
        void (^errorBlock)(NSError *) = [self.error copy];
        [self.disposable dispose];

        if (errorBlock == nil) return;
        errorBlock(e);
    }
}

- (void)sendCompleted {
    @synchronized (self) {
        void (^completedBlock)(void) = [self.completed copy];
        [self.disposable dispose];

        if (completedBlock == nil) return;
        completedBlock();
    }
}

過程回顧

去掉中間的繁雜細節,大體過程以下:
1.經過createSignal生成信號
2.經過subscribeNext肯定信號內容到來時的處理方式
3.didSubscribe block塊中異步處理完畢以後,進行sendNext、sendError和sendCompleted自動處理io

相關文章
相關標籤/搜索