iOS-RAC学习笔记(二)——RACSignal订阅

原创 2016年08月29日 17:04:38
RACSignal可以说是RAC中最重要的类。RACSignal的订阅是使用RAC的核心机制。

1. RACSignal 订阅机制

a)  RACSignal的创建:RACSignal的创建通常是使用+createSignal:这个方法创建出来的。传入参数是一个(传参是RACSubscriber的一个实例,返回是RACDisposable实例)的block;RACSignal里面有一个didSubscribe的成员变量,创建的时候把传入的block赋值给这个didSubscribe。

b)  RACSignal的订阅操作:[RACSignal  subscribeNext]这个就是RACSignal的订阅方法。以下分几步来说明。

  •  在使用这个方法的时候,会创建出一个RACSubscriber的实例(中间操作,对使用方透明),该实例实现了RACSubscriber(protocol),拥有三个block的属性,分别对应next,error,complete,即使用方调用[RACSignal  subscribeNext:error:complete]传入的三个block。

  • [RACsignal subscribe:(传参是上面创建的实例)O]之后会实际进入这个方法。这个方法的核心目的,就是执行RACSignal的didSubscribe这个block,参数就是O

  • 在didSubscribe这个执行过程中,一般都会有[subscriber sendNext/Error/complete],而这个方法的内部其实就是走subscriber的next,error,complete对应的block,也就是在[RACSignal  subscribeNext]传入的各个block

在最后一步中,深入到源码:当error或者是complete对应的block走过一次,subscriber的所有block属性都会被置为nil,不会再接受任何的数据,也就意味着本次订阅已经结束。

2. RACSignal 订阅Demo

RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber
sendNext:@"first value"];
       
return nil;
    }];
   
    [signal
subscribeNext:^(id x) {
       
NSLog(x);
    }];

如上代码,首先我们创建了一个简单的RACSignal的实例。源码如下,可以看到createSignal后面的block是直接复制到signal的didSubcribe这个对象属性中。

+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
RACDynamicSignal *signal = [[self alloc] init];
signal->
_didSubscribe = [didSubscribe copy];
return [signal setNameWithFormat:@"+createSignal:"];
}

signal之后直接被订阅,源码如下,可以看到先用subscribeNext后面的block构造出一个RACSubscriber的对象。然后去这个对象实际订阅这个signal。所以,我觉得RACSubscriber这个对象在订阅过程对使用者几乎是透明的。

- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
              NSCParameterAssert(nextBlock != NULL);
        RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
return [self subscribe:o];
}

signal被这个订阅,主要是为了让signal的didSubcribe这个block运行。如下源码中划线的那部分。

- (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;
}

signal执行didSubcribe中,有了[subscriber sendNext:@"first value”];这句代码,实际是执行subscribe的next block,也就是我们前面最简单的NSLog(X)。源码如下。

- (void)sendNext:(id)value {
@synchronized (self) {
void (^nextBlock)(id) = [self.next copy];
if (nextBlock == nil) return;

nextBlock(value);
}
}

虽说例子简单,但是我们可以看到signal中值的流向,以及监听signal的本质。各个block之间,一个扣着一个,代码的初始可读性可能比较难理解,但是真正理解之后,你会发现RAC真的很神奇。 

RACSignal的八种常用用法及例子

第1种:代替代理 RACSignal代替代理很简单,不需要像代理一样设置协议,不需要像block一样定义block类型和赋值,通过下面的一句话监听事件就能实现。 @weakify(sel...
  • jia12216
  • jia12216
  • 2017年02月17日 19:21
  • 2250

RACSignal 所有变换操作底层实现分析(2)

前言 继续分析RACSignal的变换操作的底层实现。 目录 1.过滤操作2.组合操作 一. 过滤操作 过滤操作也属于一种变换,根据过滤条件,过滤出符合条件的值。变换出来的新的信号是原信号的一...
  • ZH952016281
  • ZH952016281
  • 2016年12月05日 17:20
  • 530

ReactiveCocoa之RACSignal核心类的使用(三)

RACSignal使用步骤:   1.创建信号 + (RACSignal *)createSignal:(RACDisposable * (^)(id subscriber))didSubscrib...
  • y_csdnblog_xx
  • y_csdnblog_xx
  • 2016年05月23日 11:12
  • 1551

iOS开发:ReactiveCocoa(RAC)应用场景

一、ReactiveCocoa简介 reactiveCocoa简称RAC,它是一个三方框架,很多人把它叫做函数响应式编程框架,因为它具有函数式编程和响应式编程的特性。 由于该框架的编程思想,使得它具有...
  • indulgeIn
  • indulgeIn
  • 2016年04月10日 18:39
  • 3471

ReactiveCocoa之RACSignal核心类的使用(三)

RACSignal使用步骤:   1.创建信号 + (RACSignal *)createSignal:(RACDisposable * (^)(id subscriber))didSubscrib...
  • y_csdnblog_xx
  • y_csdnblog_xx
  • 2016年05月23日 11:12
  • 1551

ReactiveCocoa基本组件:理解和使用RACCommand

原文地址在这里。 本文源码:https://github.com/olegam/RACCommandExample   RACCommand RACCommand是ReactiveCocoa的基本组件...
  • womendeaiwoming
  • womendeaiwoming
  • 2014年07月09日 14:22
  • 15425

ReactiveCocoa中潜在的内存泄漏及解决方案

ReactiveCocoa是GitHub开源的一个函数响应式编程框架,目前在美团App中大量使用。用过它的人都知道很好用,也确实为我们的生活带来了很多便利,特别是跟MVVM模式结合使用,更是如鱼得水。...
  • ZH952016281
  • ZH952016281
  • 2016年11月15日 15:01
  • 1740

iOS-RAC学习笔记(三)——RACSignal信号流改头换面的祖师Bind

在前面提到了RAC的订阅原理,虽然中间忽略了一些其它东西(比如说RACSchedule,RACDisposable),但任何一个RACSignal的订阅事件的value的流向都是如此。既然是一步步的流...
  • chenyin10011991
  • chenyin10011991
  • 2016年08月31日 11:45
  • 1040

iOS-Network学习笔记(二)——NSURLConnection

NSURLConnection 详细讲解,delegate回调时机分析
  • chenyin10011991
  • chenyin10011991
  • 2016年06月01日 21:43
  • 487

ios学习笔记二--电影网

  • 2015年04月09日 11:56
  • 3.35MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS-RAC学习笔记(二)——RACSignal订阅
举报原因:
原因补充:

(最多只允许输入30个字)