RACSignal的Subscription過程
通過下面一張圖了解RACSignal的調用過程:
建立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中
- (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對象。
- 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方法其實是一個轉發過程。
- (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閉包
- (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自動處理
轉載 https://www.cnblogs.com/wanyakun/p/6472752.html