RAC的API

作者: 深海时代 | 来源:发表于2019-06-17 09:31 被阅读0次

    信号类:有数据产生的时候

    RACSignal;

    实质  RACDynamicSignal  -> didSubscribe(block)

    RACSubject               -> subscribers(数组)

    RACReplaySubject    -> valuesReceived(数组)

    不同的信号订阅方式不同

    RACDynamicSignal: 1.创建订阅者 RACSubscriber  2.执行didSubscribe

    RACSubject:1.创建订阅者 RACSubscriber  2.保存订阅者

    RACReplaySubject: 1.创建订阅者 RACSubscriber  2.拿到当前创建的订阅者,发送之前保存的所有值

    订阅者:发送数据 执行nextBlock

    RACSubscriber

    RACSubject

    RACReplaySubject

    信号触发结构

    A  初始化信号内容;B  信号订阅;C  信号发送回调;D  信号发送

    A createSignal后挂block(不触发任何操作)

    B subscribeNext(触发A)

    C subscribeNext后挂block(不触发任何操作)

    D sendNext(触发C)

    B->A,D->C,我们常将D写在A里构成 B->A->D->C;

    炒饭模式

    具体实现

    1.createSignal

    创建 RACDynamicSignal*  传入 didSubscribe(block)

    2.subscribeNext

    初始化一个RACSubscriber*,并把 订阅回调block赋给RACSubscriber* ->next

    实现  RACDynamicSignal*  subscribe: 包含订阅回调block的订阅者(RACSubscriber*)

    初始化一个RACPassthroughSubscriber*,->innerSubscriber *传入RACSubscriber*,->signal*传入RACDynamicSignal*,当信号的didSubscribe不为空时  进行某些判断后 执行didSubscribe并将RACPassthroughSubscriber* 当做参数传入

    3.sendNext:value

    取RACPassthroughSubscriber*->innerSubscriber 执行 sendNext

    RACSubscriber*执行next(value)方法,next为订阅回调block

    平台模式

    具体实现

    1.createSignal

    创建 RACDynamicSignal*  传入 didSubscribe(block)

    2.[RACDynamicSignal* publish];

    创建一个RACMulticastConnection对象,把RACDynamicSignal*传给 ->sourceSignal,初始化一个RACSubject*传给 ->signal;

    3.[connection.signal subscribeNext:^(id  _Nullablex) { }];

    初始化一个RACSubscriber*,并把 订阅回调block赋给->next

    实现  RACSubject*  subscribe: 包含订阅回调block的订阅者(RACSubscriber*)

    初始化一个RACPassthroughSubscriber*,->innerSubscriber *传入RACSubscriber*,->signal*传入RACSubject*。

    将RACPassthroughSubscriber*添加到RACSubject*->subscribers里。

    4.[connection connect];

    RACMulticastConnection*的sourceSignal属性执行  [RACDynamicSignal* subscribe:RACSubject*]

    初始化一个RACPassthroughSubscriber*,->innerSubscriber *传入传入RACSubject*,->signal*传入RACSubject*,当信号的didSubscribe不为空时  进行某些判断后 执行didSubscribe并将RACPassthroughSubscriber* 当做参数传入

    5.sendNext:value

    遍历RACSubject*->subscribers 取subscriber 分别执行 sendNext

    RACSubscriber*执行next(value)方法,next为订阅回调block

    不同订阅者,发送信号的方式不同

    [RACSubscriber  sendNext] :  执行nextBlock

    [RACSubject  sendNext] :  遍历自身subscribers,让他们执行nextBlock

    [RACReplaySubject sendNext] :  1.保存发送的值 2.遍历父类RACSubject的subscribers,让他们执行nextBlock

    rac常用的宏

    1.RAC(self.name_lb,text)=self.name_tf.rac_textSignal;

    将前一个属性绑定为后一个属性,当后一个属性发生变化时自动同步给前一个属性。

    2.[RACObserve(self,self.name)subscribeNext:^(id  _Nullablex) {}];

    监听一个属性,每当这个属性发生变化时执行block;

    3.@weakify(_name);@strongify(_name); 

    弱引用/强引用

    4.RACTuple*tuple=RACTuplePack(@10,@"name");

    将一个数据集合包装成元组;

    5.selfrac_liftSelector:@selector(updateUI:data:)withSignals:hotSignal,newSignal,nil];

    类线程组操作,当所有信号发送完毕后执行@selector,形参依此为信号数据。

    raccommand

    RACCOMMAND

    执行顺序:

    [commandexecute:@123];

    SignalBlock();

    command.executionSignals.next();

    signalBlock返回的信号的didSubscribe();

    内部connection.signal.next();

    bind:

    - (RACSignal *)bind:(RACSignalBindBlock (^)(void))block;

    此方法的参数是一个以 RACSignalBindBlock()为返回的block;

    此方法返回一个信号racSingal_A;

    此方法的执行就是创造返回结果信号,将block_N传给didSubscribe()。

    didSubscribe()将在racSingal_A.subscribeNext:时触发:

    racSingal_A.subscribeNext

    1.定义block

    1)completeSignal()(忽略) 2)addSignal() (addSignal(racSingal_B);为racSingal_B添加subscribeNext:block_Y();

    blockY:调用racSingal_A的sendNext)

    2.将block()运行并获取返回值RACSignalBindBlock();

    3.为当前bind方法的调用者添加subscribeNext:block_X();

    (block_X实现:触发RACSignalBindBlock(x)并获得返回信号racSingal_B;

    x为bind调用者的实参;)

    subject.sendnext(x)

    subject.sendnext(x)->subject.block_X(x)->RACSignalBindBlock(X)(中转暴露,可修改传参)->racSingal_B=[RACReturnSignal return:value];->addSignal(racSingal_B)->[racSingal_B subscribeNext:block_Y()  error:nil completed:nil]-> [RACReturnSignal subscribe:o]->[subscriber sendNext:self.value];->racSingal_B.next()->racSingal_A.sendNext

    bind

    flattenMap:

    他内部其实就是实现了一个bind,flatten的block与内部bind的入参跟返回完全一样,同样没做处理。所以他的功能就是bind的功能。

    map:

    他内部其实就是实现了一个flattenMap,map:的入参是一个(id(^)(idvalue))block类型,map方法把这个block的返回值id处理成当前信号类类型并把处理过的block传进flattenMap入参,省掉了使用者在block中封装信号的代码。

    组合:

    concat:

    通过concat:函数连接两个信号,将生成一个新信号,订阅新信号会立即触发信号1的

    - (RACDisposable*)subscribeNext:(void(^)(idx))nextBlock error:(void(^)(NSError*error))errorBlock completed:(void(^)(void))completedBlock;

    为信号1的订阅者生成  nextBlock,errorBlock,completedBlock;

    继而调用信号1的didSubscribe(subscriber);

    若信号1didSubscribe中有sendnext:则触发信号1的nextblock();继而触发新信号的nextblock;

    信号1的订阅者调用sendCompleted方法时,会调用completedBlock(),触发信号2调用subscribe:,传参为信号1的订阅者,此时调用信号2的didSubscribe(subscriber),

    若信号2didSubscribe中有sendnext:则触发信号1的nextblock();继而触发新信号的nextblock;

    then:

    内部封装的concat:通过filter:^(id_) {

    return NO;

    }返回A flattenMap: empty block的新信号,新信号由于addSignal()入参为空导致新信号subscriber.sendnext()不能被触发;

    现象,第一个信号不返回,只返回第二个信号;

    merge:

    本质上还是利用了bind:

    merge:返回组合信号的bind值,以下称信号fA&B,组合信号称信号A&B;

    订阅 fA&B 时,触发bind内部的self subscribeNext:   A&B订阅,触发merge:中的遍历,传参subscriber为 A&B的订阅者,依此触发[subscriber sendNext: signal];执行bind中A&B的nextBlock,传入子信号A或B,执行addSignal(signal),为子信号订阅事件 [subscriber sendNext:x];(即fA&B发送信号),此时,当子信号发送消息时,fA&B可以响应。

    zipWith:

    这个最简单,zipwith:返回新信号,新信号被订阅时生成sendCompletedIfNecessary与sendNext的 block,同时两个原始信号被订阅,订阅逻辑都是数组添加信号返回值,并通过sendNext()判断是否两个信号都有返回,若都返回,则新信号发送消息,结果为两信号的元组。

    combineLatest:reduce:

    这个不太想写细节了,主要是用combineLatest组合成返回元组的新信号(combineLatestWith:订阅每个原始信号以监听),然后在reduceEach:中绑定传入的block使每次调用都触发;

    其他API:

    filter:   

    此方法返回一个入参为bool类型,返回新信号,当满足bool条件时,才会收到信号内容。

    ignore:

    此方法输入一个发送值,或者输入ignoreValues,生成新信号,表示新信号会忽略输入的发送值发送;

    take:

    此方法输入数字,表示新生成的信号发送次数上限,超过次数的发送会被忽略;

    takeLast:

    此方法输入数字,表示新生成信号最后几次的值会被正常发送,前面发送的值会被发送,需要与sendCompleted一起使用;

    takeUntil:

    此方法输入一个信号,当输入信号sendCompleted或发送过一次后,新信号将忽略旧信号发送值;

    distinctUntilChanged

    当旧信号发送的值与上一次相异时,新信号才能收到值;

    skip:

    此方法输入数字,表示新生成信号会跳过旧信号前几次发送的值;

    相关文章

      网友评论

          本文标题:RAC的API

          本文链接:https://www.haomeiwen.com/subject/amcbaqtx.html