RAC学习笔记(二)

热信号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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容