对于最近公司一个项目涉及到了RAC
, 再结合着网上其他大佬的文章做一下整理.
RAC
的简介就不做介绍了, 百度会不会??
如果你不知道RAC
是什么, 一点没了解过, 没关系, 看了你也不会 哈哈哈哈哈哈哈哈😆
切入正题:
项目使用swift
的话使用cocoapods
导入pod ‘ReactiveObjC’, ‘~> 3.0.0’
然后在导入头文件ReactiveObjC.h
就可以好了
3.0.0以上
的版本支持了swift
,
如果你是纯OC
工程,建议使用3.0.0
版本。
本篇主要介绍一下RACSignal
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: %@",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,
这个时候我们再来看下创建信号的方法
//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);
}];
它给我们一个subscriber
而这个sbuscriber
就是我们调用订阅信号的方法所创建的subscriber
,然后我们要用这个订阅者发送信息
那我们订阅的信号啥时候调用呢?
当我们的订阅者发送消息的时候就会调用。
这个时候我们看下订阅者发送信息的方法内部做了什么
- (void)sendNext:(id)value {
@synchronized (self) {
void (^nextBlock)(id) = [self.next copy];
if (nextBlock == nil) return;
nextBlock(value);
}
}