1.信号的使用
RACSignal* signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"message"];
return nil;
}];
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"received:%@", x);
}];
// 控制台输出: received:message
2.具体流程如下:
(1)创建信号:创建 signal 信号对象的时候,最终创建的是 RACSignal 的子类 RACDynamicSignal 的对象,并传入一个名为 didSubscribe,参数为 subscriber 订阅者对象,返回值为 RACDisposable 对象的 block回调,保存到 signal 对象中;(此时信号为冷信号)
===== RACDynamicSignal.h =====
@property (nonatomic, copy, readonly) RACDisposable * (^didSubscribe)(id<RACSubscriber> subscriber);
===== 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:"];
}
(2)订阅信号:订阅者订阅信号的时候,需要调用 signal 对象的 subscribeNext: 方法,此方法会创建一个订阅者对象 subscriber,并传入一个名为 nextBlock,参数为 id 类型, 返回值为 RACDisposable 对象的 block回调,保存到subscriber 对象中;
然后调用 signal 对象的订阅方法 subscribe: ,参数为前面的 subscriber 对象,返回值为 RACDisposable 对象,此方法中会调用 signal 对象中保存的 didSubscribe 回调;(订阅后信号变为热信号)
===== RACSubscriber.m =====
@property (nonatomic, copy) void (^next)(id value);
===== RACSignal.m =====
- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
NSCParameterAssert(nextBlock != NULL);
RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
return [self subscribe:o];
}
===== RACDynamicSignal.m =====
- (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;
}
(3)发送信号:didSubscribe block 实现中会调用 subscriber 的 sendNext: 方法,发送消息给信号对象,表示订阅者已经订阅信号,sendNext: 方法会同步取出订阅者对象中保存的 nextBlock 并执行,此时信号订阅流程结束。
- (void)sendNext:(id)value {
@synchronized (self) {
void (^nextBlock)(id) = [self.next copy];
if (nextBlock == nil) return;
nextBlock(value);
}
}
流程如下图:
RACSignal.png另外,前面创建订阅者时,传入了三个参数,nextBlock,error,completed;创建信号的时候,在网络请求失败的回调中,我们要[subscriber sendError:netError],也就是发送错误信息,然后再订阅错误事件,也就是调用 subscriberError: 方法,这样就完成了错误信息的订阅。
completed 事件比较特殊,它有终止订阅关系的意味,先大致了解一下RACDispoable对象,我们知道,订阅关系需要有终止的时候,比如,在tableViewCell的复用的时候,cell会订阅model类产生一个信号,但是当cell被复用的时候,如果不把之前的订阅关系取消掉,就会出现同时订阅了2个model的情况。我们可以发现 subscribeNext、subscribeError、subscribeCompleted 事件返回的都是 RACDisopable 对象,当我们希望终止订阅的时候,调用[RACDisposable dispose]
就可以了。completed 也是这个原理。
网友评论