魏名华

不要偷懒,做更好的自己

Nothing


No Welcome Message

Rac学习笔记

RAC学习笔记

RACSignal的Subscription深入分析

冷信号的创建和订阅过程

-(RACSignal *)signInSignal {
// part 1:[RACSignal createSignal]来获得signal
  return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [self.signInService
     signInWithUsername:self.usernameTextField.text
     password:self.passwordTextField.text
     complete:^(BOOL success) {

    // part 3: 进入didSubscribe,通过[subscriber sendNext:]来执行next block
       [subscriber sendNext:@(success)];
       [subscriber sendCompleted];
     }];
    return nil;
  }];
}

// part 2 : [signal subscribeNext:]来获得subscriber,然后进行subscription
[[self signInSignal] subscribeNext:^(id x) { 
    NSLog(@"Sign in result: %@", x); 
}];

步骤一:[RACSignal createSignal]来获得signal

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:" ];
}

[RACSignal createSignal]会调用子类RACDynamicSignal的createSignal来返回一个signal,并在signal中保存后面的 didSubscribe这个block

步骤二:[signal subscribeNext:]来创建subscriber,然后进行subscription

RACSignal.m中:

- ( RACDisposable *)subscribeNext:( void (^)( id x))nextBlock {
  RACSubscriber *o = [ RACSubscriber   subscriberWithNext :nextBlock error : NULL   completed : NULL ];
  return [ self  subscribe :o];
}

RACSubscriber.m中:

+ ( 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.m中:

- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
    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;
}

[signal subscribeNext]: -> 先会创建一个subscriber,这个subscriber中保存了nextBlock、errorBlock、completedBlock -> 由于这个signal其实是RACDynamicSignal类型的,这个[self subscribe]方法会调用createSignal时保存的didSubscribe这个block,参数就是subscriber, 执行didSubscribe这个block里面的代码

步骤三:进入didSubscribe,执行代码,异步任务完成后,执行[subscriber sendNext:]来执行next block,发送结果给订阅者

RACSubscriber.m中:

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

任何时候这个[subscriber sendNext:],就直接调用nextBlock

signal的subscription过程回顾

从上面的三个步骤,我们看出:

先通过createSignal和subscribeNext这两个调用,声明了流中value到来时的处理方式 didSubscribe block块中异步处理完毕之后,subscriber进行sendNext,自动处理