iOS: RAC篇 - RACSignal

对于最近公司一个项目涉及到了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); 
      } 
}
这里的代码很简洁了 主要就是做了一件事,如果nextblock不为空就把传进来传value原封不动的调用出去。 而这个nextblock就是我们在订阅信号的时候创建的那个subscriber所保存的nextblock

所以RACSignal的处理流程就是

1. 创建信号的block会在订阅信号的时候调用
2. 订阅信号的block会在订阅者发布信息的时候调用
流程图.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容