RACSubscriber

来源:互联网 发布:中国联通宽带提速软件 编辑:程序博客网 时间:2024/05/17 23:10

RACSubscriber订阅者是一个抽象的概念,所有实现了 RACSubscriber 协议的类都可以作为信号源的订阅者。

在 RACSubscriber 协议中,声明了四个必须实现的方法:

@protocol RACSubscriber <NSObject>@required/// Sends the next value to subscribers.////// value - The value to send. This can be `nil`.- (void)sendNext:(id)value;/// Sends the error to subscribers.////// error - The error to send. This can be `nil`.////// This terminates the subscription, and invalidates the subscriber (such that/// it cannot subscribe to anything else in the future).- (void)sendError:(NSError *)error;/// Sends completed to subscribers.////// This terminates the subscription, and invalidates the subscriber (such that/// it cannot subscribe to anything else in the future).- (void)sendCompleted;/// Sends the subscriber a disposable that represents one of its subscriptions.////// A subscriber may receive multiple disposables if it gets subscribed to/// multiple signals; however, any error or completed events must terminate _all_/// subscriptions.- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)disposable;

其中 -sendNext: 、-sendError: 和 -sendCompleted 分别用来从 RACSignal 接收 next 、error 和 completed 事件,而 -didSubscribeWithDisposable: 则用来接收代表某次订阅的 disposable 对象。

订阅者对信号源的一次订阅过程可以抽象为:通过 RACSignal 的 -subscribe: 方法传入一个订阅者,并最终返回一个 RACDisposable 对象的过程:

这里写图片描述

#if 1+ (void) testRACSignal{    // RACSignal底层实现:    // 1.创建信号,首先把didSubscribe保存到信号中,还不会触发。    // 2.当信号被订阅,也就是调用signal的subscribeNext:nextBlock    // 2.2 subscribeNext内部会创建订阅者subscriber,并且把nextBlock保存到subscriber中。    // 2.1 subscribeNext内部会调用siganl的didSubscribe    // 3.siganl的didSubscribe中调用[subscriber sendNext:@1];    // 3.1 sendNext底层其实就是执行subscriber的nextBlock    // 1.创建信号    RACSignal *siganl = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {        // block调用时刻:每当有订阅者订阅信号,就会调用block。        // 2.发送信号        [subscriber sendNext:@1];        // 如果不在发送数据,最好发送信号完成,内部会自动调用[RACDisposable disposable]取消订阅信号。        [subscriber sendCompleted];        return [RACDisposable disposableWithBlock:^{            // block调用时刻:当信号发送完成或者发送错误,就会自动执行这个block,取消订阅信号。            // 执行完Block后,当前信号就不在被订阅了。            NSLog(@"信号被销毁");        }];    }];    // 3.订阅信号,才会激活信号.    [siganl subscribeNext:^(id x) {        // block调用时刻:每当有信号发出数据,就会调用block.        NSLog(@"接收到数据:%@",x);    }];}#endif

RACPassthroughSubscriber

eactiveCocoa 就引入了 RACPassthroughSubscriber 类,它是 RACSubscriber 类的一个装饰器,封装了一个真正的订阅者 RACSubscriber 对象,它负责转发所有事件给这个真正的订阅者,而当此次订阅被取消时,它就会停止转发。

#pragma mark RACSubscriber- (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];}- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)disposable {    if (disposable != self.disposable) {        [self.disposable addDisposable:disposable];    }}

在 ReactiveCocoa 中,我们倾向于隐藏订阅者,因为外界根本不需要知道订阅者的存在,这是内部的实现细节。这样做的主要目的是进一步简化信号源的订阅逻辑,客户端代码只需要关心它所需要的值就可以了,根本不需要关心内部的订阅过程。

原创粉丝点击