RAC实践和注意事项

RAC:包括信号源、订阅者、调度器、清洁工

信号源:

RACSignal,代表未来将会被传送的值,他是一种push-driven流,RACSignal可以向订阅者发送三种不同类型的值:sendNext(正常信号)、error(错误)、completed(信号已经发送结束,不会再传给订阅者);

信号的发送都是通过-subscribe:这个方法来实现的,他也是信号和订阅者的唯一桥梁。

RACSubject,代表可以手动控制的信号,可以看做他是RACSinal的可变版本(类似数据和可变数据),因为它继承RACSinal所以可以当做信号,但它又实现了RACSubscriber协议,所以他还可以作为订阅者订阅其他信号。(它太灵活,所以正常情况下我们不用他,一般用它的双性性来处理 网络或其他 fail(错误逻辑))

充当两种角色实例:

RAC实践和注意事项_第1张图片
RACSubject订阅了RACSignal,又被订阅者1、2、3订阅
RAC实践和注意事项_第2张图片
统一处理错误逻辑实例


RACSequence:代表一个不可变的序列(和链表一样结构一样),它不可以直接被订阅,但它可以RACSingal随意的转换。他主要是用来处理OC中集合的,例如(遍历等)循环数组等。

注意:RACSequence中包含的值在默认情况下是懒计算的,即只有在真正用到的时候才会被计算,并且只会计算一次,如果我们只用到了一个RACSequence中的部分值的时候,它就在不知不觉中提高了我们应用的性能,(所以我们在使用时,要先看下我们需要的数据和后台返回给我们的数据,在去看是直接在获取数据时转换模型,还是用的使用转换模型)【性能优化问题】

RAC实践和注意事项_第3张图片
处理集合实例

订阅者:所有实现RACSubscriber的类都可以作为订阅者

注意:一个订阅者可以订阅多个信号源的,而且他也可以随时取消任意一个订阅;

信号是可以转成订阅者的,只要遵守RACSubscriber协议就可以。

调度器:

扮演着调度器的角色,本质上,它就是用GCD的串行队列来实现的,并且支持取消操作

RAC实践和注意事项_第4张图片
取消请求的例子

清洁工:

垃圾回收,这个是自动回收的,一般在信号订阅完成会自发进行的。


特殊的一个存在:事件控制器

RACCommand类用于表示事件的执行,一般来说是在UI上的某些动作来触发这些事件,比如点击一个按钮。RACCommand的实例能够决定是否可以被执行,这个特性能反应在UI上,而且它能确保在其不可用时不会被执行。通常,当一个命令可以执行时,会将它的属性allowsConcurrentExecution设置为它的默认值:NO,从而确保在这个命令已经正在执行的时候, 不会同时再执行新的操作。命令执行的返回值是一个RACSignal,因此我们能对该返回值进行next:,completed或error:,这在下文会有所展示。

RACCommand的基本使用

1.executionSignals:需要执行的block成功的时候返回的信号,他是在主线程执行的。

2.executing:判断当前的block是否在执行,执行完之后会返回@(NO).

3.enabled:当前命令是否enabled,默认是no,他也可以根据enableSignal来设置或者allowsConcurrentExecution设置为NO的时候(command已经开始执行)4.errors:执行command的时候获取的error都会通过这个信号发送5.allowsConcurrentExecution:是否允许并发执行command,默认是NO。6.initWithSignalBlock:(RACSignal * (^)(id input))signalBlock:初始化RACCommand,参数为返回一个信号的block,即block返回的是executionSignals

7.- (id)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(id input))signalBlock:第一个参数设置当前command是否可用,第二个是执行的block。enableed默认是yes,所以第二个参数也可以为nil。

8.execute:(id)input:调用command,input为executionSignals的订阅者发送的值


--------------------------完美分割线-------------------------------------------

RAC的三个作用:

1、数据绑定:这个特别是在cell赋值操作时,我们平常是直接懒加载赋值,有了RAC我们可以在声明对象时就可以直接进行数据绑定。

2、函数式编程:(利用block嵌套block,所有的操作都在一些列的操作中完成)

3、响应式编程:几乎把ios中的所有响应监听都统一化,耦合性非常低,监听的事情和相应的事情都可以在一起处理,不在需要相互的跳转。

其他方式也可以是实现MVVM,为什么要用这个方式:

1、模型转换上,可以直接用RACSequence直接处理,内部是懒加载实现的,有一定个的内存优化

2、错误统一处理上,我们可以通过RACSuject同意处理错误逻辑

3、逻辑处理上,通过信号统一管理数据,信号激活也是懒加载形式的,有一定的性能优化,在下拉刷新上也大大减少的代码量。

4、通过RACCommand进行管理,我们可以按需执行,实时检测执行状态,是否可以被执行等。

5、代码上的简洁,省去大量的if else  for等,也省去了很多的方法嵌套方法,所有的下一步事件都可以通过嵌套block来实现。


相应问题:

1、模型转换

RAC提供的模型转换是懒加载的(用数据中的哪一个才进行转换哪一个),我们要根据自己的需要看看是直接在数据源转换模型,还是在使用时在进行模型转换。

同样的数据直接用mj_的方法转换,耗时: 0.009762,用RAC自带的dictArr.rac_sequence map进行循环转换耗时: 0.012227,明显体现出mj_的

2、RAC优势:函数响应式框架

响应式编程:不需要考虑顺序,只需要知道结果,万物皆是流

函数式编程:把操作尽量写成一系列嵌套或方法调用,在ios中就是block中套block

3、数据绑定:

注意我们观察的是模型对象,并不是模型对象里面的某一个属性,这样是观察不到的。

注意事项:在绑定的时候我们可以在函数里添加filter、map、skip、、等方法,不需要在不断的进行循环或者if else了,非常的方便,也便于管理。

4、替换对象:代理、按钮事件、消息中心、KVO、KVC、监听文本框文字改变、等等,都可以通过流对象、订阅流、管理流、销毁流来处理,非常的耦合,不需要来回的相互跳转了。

5、用了RAC代码中少了相互跳转、少了if else、少了for循环、少了代理等等,都是代码的优化、少了方法和方法之间的调用,多了block的嵌套。

你可能感兴趣的:(RAC实践和注意事项)