RAC - RACSignal
Posted MinggeQingchun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RAC - RACSignal相关的知识,希望对你有一定的参考价值。
文章系列
《RACSignal 》
《RACDisposable》
《RACSubject、RACReplaySubject》
《iOS RAC - 基本用法》
《iOS RAC - 定时器》
《iOS RAC - RACMulticastConnection》
《iOS RAC - RACCommand》
《iOS RAC - 核心方法bind》
《iOS RAC - 集合RACTuple、RACSequence》
《iOS RAC - rac_leftSelector》
《iOS RAC - 映射》
《iOS RAC - 过滤》
《iOS RAC - 登录页面,MVVM》
- 项目中如果没有使用swift的话使用cocoapods 导入
pod ‘ReactiveObjC’, ‘~> 3.0.0’
然后在导入头文件ReactiveObjC.h
就可以使用了,3.0.0
以上的版本支持了swift,如果你是纯OC工程,不建议使用3.0.0
以上的版本。
RACSignal:顾名思义,信号类,signal本身不具备发送信号的能力,下面通过代码来看看。
在创建RACSignal中先说一下RAC的三部曲
- 1 创建信号
- 2 订阅信号
- 3 发送信息
//1、创建信号量
RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
NSLog(@"创建信号量");
//3、发布信息
[subscriber sendNext:@"I'm send next data"];
NSLog(@"那我啥时候运行");
return nil;
}];
//2、订阅信号量
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
代码分析 - 创建信号
[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
return nil;
}];
这里要创建一个Signal对象,然后它马上给我一个block,
并且在block中要返回一个RACDisposable
对象,
刚开始接触RAC的我哪里知道这个是什么鬼,直接返回nil
至此我们完成了第一步,创建信号
然后其内部实现我们并不了解,于是我们点击进去看看其内部如何实现的。
+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
return [RACDynamicSignal createSignal:didSubscribe];
}
可以看到其内部创建了一个RACDynamicSignal
信号,并且把didSubscribe
这个block也传过去了,然后在点进去看看
+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
RACDynamicSignal *signal = [[self alloc] init];
signal->_didSubscribe = [didSubscribe copy];
return [signal setNameWithFormat:@"+createSignal:"];
}
这段代码意思就很清楚了,创建一个RACDynamicSignal
,保存didSubscribe
这个block,返回RACDynamicSignal
这个对象。
通过上面的了解,我们可以知道,创建信号这个方法内部会帮我们创建一个RACDynamicSignal
并且保存一个didSubscribe
block。
但是这个block什么时候调用呢?
没错就是在我们订阅信号的时候调用
代码分析 - 订阅信号
//2、订阅信号量
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
这里一订阅信号就给我一个block,并且还带一个参数x,并不知道是饿什么东西,就先打印出来。
然后我们点击进去看下内部实现
- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
NSCParameterAssert(nextBlock != NULL);
RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
return [self subscribe:o];
}
- 1、创建一个订阅者
+ (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;
}
保存了nextblock
- 2、 调用
subscribe
方法
- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
NSCParameterAssert(subscriber != nil);
RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
//这里判断didSubcribe是否为空
if (self.didSubscribe != NULL) {
RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
//这里就在调用didSubscribe方法,并且把刚才传入的subscriber调用出去
RACDisposable *innerDisposable = self.didSubscribe(subscriber);
[disposable addDisposable:innerDisposable];
}];
[disposable addDisposable:schedulingDisposable];
}
return disposable;
}
在这个方法中会判断是有有didSubscriber,
如果有就调用block并且把传入进来的subscriber作为block的参数调用出去
订阅信号之后就会运行创建信号的block,
这个时候我们再来看下创建信号的方法
[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
NSLog(@"创建信号量");
//3、发布信息
[subscriber sendNext:@"I'm send next data"];
NSLog(@"那我啥时候运行");
return nil;
}];
//2、订阅信号量
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
它给我们一个subscriber
而这个sbuscriber就是我们调用订阅信号的方法所创建的subscriber,然后我们要用这个订阅者发送信息
那我们订阅的信号啥时候调用呢?
- 当我们的订阅者发送消息的时候就会调用。
这个时候我们看下订阅者发送信息的方法内部做了什么
- (void)sendNext:(id)value {
@synchronized (self) {
void (^nextBlock)(id) = [self.next copy];
if (nextBlock == nil) return;
nextBlock(value);
}
}
这里的代码很简洁了 主要就是做了一件事,如果nextblock不为空就把传进来传value原封不动的调用出去。 而这个nextblock就是我们在订阅信号的时候创建的那个subscriber所保存的nextblock。
所以RACSignal的处理流程就是
- 创建信号的block会在订阅信号的时候调用
- 订阅信号的block会在订阅者发布信息的时候调用
以上是关于RAC - RACSignal的主要内容,如果未能解决你的问题,请参考以下文章
RAC篇(上) - RACSignal & RACSubject
OC + RAC RACSubject和RACSignal的区别