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

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真的很神奇。 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值