RACSignal分析

栏目: Objective-C · 发布时间: 5年前

内容简介:信号的使用,包括:创建信号、发送信号、订阅信号获取信号的方式有很多种:最简单的信号是单元信号,有4种:

信号的使用,包括:创建信号、发送信号、订阅信号

创建信号

获取信号的方式有很多种:

  • 创建单元信号

  • 创建动态信号

  • 通过Cocoa桥接

  • 从别的信号变换而来

  • 由序列变换而来

单元信号

最简单的信号是单元信号,有4种:

// return信号:被订阅后,马上产生一个值事件,同时产生一个完成事件
RACSignal *signal1 = [RACSignal return:someObject];

// error信号:被订阅后,马上产生一个错误事件,同时产生一个完成事件
RACSignal *signal2 = [RACSignal error:someError];

// empty信号:被订阅后,马上产生一个空事件,同时产生一个完成事件
RACSignal *signal3 = [RACSignal empty];

// never信号:永远不产生事件,同时产生一个完成事件
RACSignal *signal4 = [RACSignal never]; 复制代码

动态信号

RACSignal *signal5 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
  [subscriber sendNext:@"1"];
  [subscriber sendNext:@"2"];
  [subscriber sendCompleted]; 
  return [RACDisposable disposableWithBlock:^{
    
  }];
}];复制代码

Cocoa桥接

RAC为大量的Cocoa类型提供便捷的信号桥接工具,如下是一些常见的桥接方式:

RACSignal *signal6 = [object rac_signalForSelector:@selector(setFrame:)];
RACSignal *signal7 = [control rac_signalForControlEvents:UIControlEventTouchUpInside];
RACSignal *signal8 = [object rac_willDeallocSignal];
RACSignal *signal9 = RACObserve(object, keyPath);复制代码

信号变换

RACSignal *signal10 = [signal1 map:^id(id value) {
    return someObject;
}];复制代码

序列变换

RACSignal *signal11 = sequence.signal;复制代码

订阅信号

订阅信号的方式有3种:

  • 通过 subscribeNext:error:completed: 方法订阅

  • RAC宏绑定

  • Cocoa桥接

subscribeNext:error:completed: 是最基础的信号订阅方法;

RAC宏绑定 可以使用 RAC() 宏 如:RAC(view, backgroundColor) = signal;

Cocoa桥接 [object rac_liftSelector:@selector(someSelector:) withSignals:signal1, signal2, nil];

订阅过程

所谓订阅过程指的是信号被订阅的处理逻辑,如下是简单的例子:

RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [subscriber sendNext:@"1"];    
    [subscriber sendNext:@"2"];
    [subscriber sendCompleted];     
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"dispose");       // 当错误事件或者完成事件产生时,该block被调用
    }];
}];
[signal subscribeNext:^(id x) {
    NSLog(@"next value is :  %@", x);
} error:^(NSError *error) {
    NSLog(@"error : %@", error);
} completed:^{
    NSLog(@"completed");
}];复制代码

信号的各类操作

RACTuple , 就像NSArray数组:

RACTuple *tuple = RACTuplePack(@1, @"haha");
id first = tuple.first;
id second = tuple.second;
id last = tuple.last;
id index1 = tuple[1];

RACTupleUnpack(NSNumber *num, NSString *str) = tuple;
复制代码

信号的操作一般分为单个信号的变换、多个信号的组合及高阶操作

单个信号的变换

分为值操作、数量操作、时间操作、副作用操作

值操作

map 做一个映射,返回新的信号

mapReplace 等价于返回同一个值得map

reduceEach,是map:的变体。当signalA的值事件包裹的数据是RACTuple类型时,才可以使用该操作,将RACTuple组合成一个

reduceApply,要求值事件包裹的数据类型是RACTuple,并且该RACTuple的第一个元素是一个block,后面的元素作为该block的参数传入,返回该block的执行结果。

逻辑操作:not, and, or

数量操作

filter 过滤

ignore 忽略

take 只取前n个

skip 过滤掉前n个

startWith 从某个元素开始

distinctUntilChanged 去重复

repeat 重复

retry [signalA retry:2]; 重试几次

collect 把所以集合到一个

aggregate 和sacn 类似但有区别 scan 实时输出,aggregate 最终结束才输出,出错则不输出

副作用操作

doNext doError doCompleted

initially finally

时间操作

delay 延迟

throttle:1 当signalA事件流产生一个值事件时,若1 s内没有其他的值事件产生,则signalB事件流中也会产生该值事件;当signalA事件流产生一个值事件时,若1s内有其他的值事件产生,则signalB会过滤掉该值事件,对于signalA中的最后一个值事件,signalB事件流中总会也包含它

多个信号的组合

concat 加在后面

merge 插入进来

zip 两个信号合成一个RACTuple

combineLatest a信号来一个值事件就和b信号最近的值事件组合

sample 类似取景和快门

takeUntil signalC事件流中的事件和signalA一一对应,直到signalB事件流中出现了信号,事件流就终结。

信号的高阶操作

switchToLatest 读到新的信号就把之前的信号关闭

if then else 其实就是switchToLatest的实现

+ (RACSignal *)if:(RACSignal *)boolSignal 
        then:(RACSignal *)trueSignal 
    else:(RACSignal *)falseSignal {
    .....  
    return [[[boolSignal    map:^(NSNumber *value) {      
        NSCAssert([value isKindOfClass:NSNumber.class], @"Expected %@ to send BOOLs, not %@", boolSignal, value);​      
        return (value.boolValue ? trueSignal : falseSignal);    
    }] switchToLatest]    
    setNameWithFormat:@"+if: %@ then: %@ else: %@", boolSignal, trueSignal, falseSignal];
}复制代码

代替代理

  • rac_signalForSelector 用于代替代理

代替 KVO

  • rac_valuesAndChangesForKeyPath 用于监听某个对象的某个属性的改变

代替事件监听

  • rac_signalForControlEvents 用于监听某个事件

代替通知

  • rac_addObserverForName 用于监听某个通知,且不需要在 - (void)dealloc 中移除监听

监听文本框文字改变

  • rac_textSignal 用于监听文本框文字变化

监听手势

  • rac_gestureSignal 用于监听手势操作

多个请求完成时,再执行后继操作

  • rac_liftSelector:withSignalsFromArray:Signals 当传入的 Signals,每一个 Signal 都至少 sendNext 过一次,就会去触发第一个 selector 参数的方法。

信号的相关操作

  • bind :函数会返回一个新的信号 N。整体思路是对原信号 O 进行订阅,每当信号 O 产生一个值就将其转变成一个中间信号 M ,并马上订阅 M ,之后将信号M的输出作为新信号 N 的输出。
  • map \ flattenMap :用于把源信号内容映射成新的内容(信号)。
  • concat :组合,按一定顺序拼接信号,当多个信号发出的时候,有顺序的接收信号。
  • then :用于连接两个信号,当第一个信号完成,才会连接 then 返回的信号。
  • merge :把多个信号合并为一个信号,任何一个信号有新值的时候就会调用。
  • zipWith :把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元组,才会触发压缩流的 next 事件。
  • combineLatest :将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的 signal 至少都有过一次 sendNext ,才会触发合并的信号。
  • reduce :聚合,用于信号发出的内容是元组,把信号发出元组的值聚合成一个值。
  • filter :过滤信号,使用它可以获取满足条件的信号。
  • ignore :忽略某些值的信号,使用 RACObserve 时可配合使用,其实现由 filter 完成。
  • distinctUntilChanged :实现是用 bind 来完成的,每次变换中都记录一下原信号上一次发送过来的值,并与这一次进行比较,如果是相同的值,就「吞」掉,返回 empty 信号。只有和原信号上一次发送的值不同,变换后的新信号才把这个值发送出来。
  • take :从开始一共取 N 次的信号。
  • takeLast :取最后 N 次的信号,前提条件:订阅者必须调用完成,因为只有完成,才知道总共有多少信号。
  • takeUntil :获取信号直到某个信号执行完成。
  • skip :跳过几个信号,不接受。
  • switchToLatest :用于 signalOfSignals (信号的信号),有时候信号也会发出信号,会在 signalOfSignals 中,获取 signalOfSignals 发送的最新信号。
  • doNext :执行 next 之前,会先执行这个 Block 。
  • doCompleted :执行 sendCompleted 之前,会先执行这个Block 。
  • timeout :超时,可以让一个信号在一定的时间后,自动报错。
  • interval :定时:每隔一段时间发出信号。
  • delay :延迟发送 next
  • retry :重试,只要失败,就会重新执行创建信号中的 block ,直到成功。
  • replay :重放,当一个信号被多次订阅,反复播放内容。
  • throttle :节流,当某个信号发送比较频繁时,可以使用节流,在某一段时间不发送信号内容,过了一段时间获取信号的最新内容发出。

ReactiveCocoa 常见宏

  • RAC(TARGET, ...) 用于绑定某个对象的某个属性
  • RACObserve(TARGET, KEYPATH) 用于监听某个对象的某个属性,返回的是信号
  • @weakify(Obj) & @strongify(Obj) 配套使用

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

金字塔原理

金字塔原理

[美] 巴巴拉·明托 / 王德忠、张珣 / 民主与建设出版社 / 2002-12 / 39.80元

《金字塔原理》是一本讲解写作逻辑与思维逻辑的读物,全书分为四个部分。 第一篇主要对金字塔原理的概念进行了解释,介绍了如何利用这一原理构建基本的金字塔结构。目的是使读者理解和运用简单文书的写作技巧。 第二篇介绍了如何深入细致地把握思维的环节,以保证使用的语句能够真实地反映希望表达的思想要点。书中列举了许多实例,突出了强迫自己进行“冷静思维”对明确表达思想的重要性。 第三篇主要针对的......一起来看看 《金字塔原理》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具