美文网首页
RAC学习笔记(二)

RAC学习笔记(二)

作者: 咩咩sheep | 来源:发表于2017-07-27 16:28 被阅读0次

    热信号RACSubject

    RACSubjectRACSignal的子类,RACSubject实现了RACSubscriber协议,RACSubject的订阅过程和RACSignal的区别很大,subject内部有一个可变数组subscribers,这个数组保存了所有的订阅者,所以当执行sendNext操作时,所有已经订阅的都能收到消息

    RACSubject *subject = [RACSubject subject];
        [subject subscribeNext:^(id  _Nullable x) {
            NSLog(@"1st subject: %@",x);
        }];
        [subject sendNext:@"1"];
        [subject subscribeNext:^(id  _Nullable x) {
            NSLog(@"2st subject: %@",x);
        }];
        [subject sendNext:@"2"];
        [subject subscribeNext:^(id  _Nullable x) {
            NSLog(@"3st subject: %@",x);
        }];
        [subject sendNext:@"3"];
        [subject sendCompleted];
    

    log信息如下

    1st subject: 1
    1st subject: 2
    2st subject: 2
    1st subject: 3
    2st subject: 3
    3st subject: 3
    

    订阅的内部实现

    - (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
        subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
        NSMutableArray *subscribers = self.subscribers;
        @synchronized (subscribers) {
            [subscribers addObject:subscriber];
        }
        return disposable;
    }
    

    sendNext的操作其实是一个遍历subscribers数组的过程

    - (void)sendNext:(id)value {
        [self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) {
            [subscriber sendNext:value];
        }];
    }
    

    子类RACBehaviorSubject和RACReplaySubject

    RACBehaviorSubject在订阅时会向订阅者发送最新的消息,RACReplaySubject在订阅之后可以重新发送之前的所有消息序列。

    • RACBehaviorSubject
      它里面有个currentValue变量,每次执行sendNext的时候currentValue会被替换成当前的value,订阅的时候会执行[subscriber sendNext:self.currentValue],所以当前订阅者会收到最近的一条消息,还有当前的消息。因为sendNext:(id)value方法执行了[super sendNext:value],所以之前的订阅者也能收到当前消息 ,还用上面的代码演示
    RACBehaviorSubject *subject = [RACBehaviorSubject subject];
        [subject subscribeNext:^(id  _Nullable x) {
            NSLog(@"1st subject: %@",x);
        }];
        [subject sendNext:@"1"];
        [subject subscribeNext:^(id  _Nullable x) {
            NSLog(@"2st subject: %@",x);
        }];
        [subject sendNext:@"2"];
        [subject subscribeNext:^(id  _Nullable x) {
            NSLog(@"3st subject: %@",x);
        }];
        [subject sendNext:@"3"];
        [subject sendCompleted];
    

    log信息如下

    1st subject: (null)
    1st subject: 1
    2st subject: 1
    1st subject: 2
    2st subject: 2
    3st subject: 2
    1st subject: 3
    2st subject: 3
    3st subject: 3
    
    • RACReplaySubject
      它里面有个valuesReceived变量,用来保存曾经发送过得消息值,每次订阅的时候会触发遍历
    for (id value in self.valuesReceived) {
                    if (compoundDisposable.disposed) return;
    
                    [subscriber sendNext:(value == RACTupleNil.tupleNil ? nil : value)];
                }
    

    这样当前的订阅者就会收到之前的消息
    同时sendNext操作调用super操作,发送当前消息给之前的订阅者,演示代码

    RACReplaySubject *subject = [RACReplaySubject subject];
      [subject subscribeNext:^(id  _Nullable x) {
          NSLog(@"1st subject: %@",x);
      }];
      [subject sendNext:@"1"];
      [subject subscribeNext:^(id  _Nullable x) {
          NSLog(@"2st subject: %@",x);
      }];
      [subject sendNext:@"2"];
      [subject subscribeNext:^(id  _Nullable x) {
          NSLog(@"3st subject: %@",x);
      }];
      [subject sendNext:@"3"];
      [subject sendCompleted];
    

    log信息如下

    1st subject: 1
    2st subject: 1
    1st subject: 2
    2st subject: 2
    3st subject: 1
    3st subject: 2
    1st subject: 3
    2st subject: 3
    3st subject: 3
    

    相关文章

      网友评论

          本文标题:RAC学习笔记(二)

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