iOS RAC常用方法
一直想写篇关于RAC的文章,一是分享二是做为笔记,由于项目忙先简单的贴一个自己当初学习的时候代码吧
一、RACCommand
// RACCommand 的使用: 使用场景,监听按钮点击,网络请求
- (void)RACCommand{ // 1.创建命令
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) { NSLog(@"执行命令");
// 创建空信号,必须返回信号
// return [RACSignal empty]; // 2.创建信号,用来传递数据
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@"请求数据"]; // 注意:数据传递完,最好调用sendCompleted,这时命令才执行完毕。
[subscriber sendCompleted]; return nil;
}]; }]; // 强引用命令,不要被销毁,否则接收不到数据
self.conmmand = command; // 3.订阅RACCommand中的信号
[command.executionSignals subscribeNext:^(id x) { NSLog(@"command.executionSignals %@",x);
[x subscribeNext:^(NSString *x) { NSLog(@"x subscribeNext %@",x);
}]; }]; // RAC高级用法
// switchToLatest:用于signal of signals,获取signal of signals发出的最新信号,也就是可以直接拿到RACCommand中的信号
// [command.executionSignals.switchToLatest subscribeNext:^(id x) {
//
// NSLog(@"command.executionSignals.switchToLatest %@",x);
// }]; // 4.监听命令是否执行完毕,默认会来一次,可以直接跳过,skip表示跳过第一次信号。
[[command.executing skip:1] subscribeNext:^(id x) { if ([x boolValue] == YES) {
// 正在执行
NSLog(@"正在执行"); }else{
// 执行完成
NSLog(@"执行完成");
} }];
// 5.执行命令
[self.conmmand execute:@1]; }
二、RACMulticastConnection
// RACMulticastConnection 使用场景:用于当一个信号,被多次订阅时,为了保证创建信号时,避免多次调用创建信号中的block,造成副作用,可以使用这个类处理
- (void)RACMulticastConnection{
// 需求:假设在一个信号中发送请求,每次订阅一次都会发送请求,这样就会导致多次请求。
// 解决:使用RACMulticastConnection就能解决.
// 1.创建请求信号
// RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//
//
// NSLog(@"发送请求");
//
// return nil;
// }];
// // 2.订阅信号
// [signal subscribeNext:^(id x) {
//
// NSLog(@"接收数据");
//
// }];
// // 2.订阅信号
// [signal subscribeNext:^(id x) {
//
// NSLog(@"接收数据");
//
// }];
// // 3.运行结果,会执行两遍发送请求,也就是每次订阅都会发送一次请求 // RACMulticastConnection:解决重复请求问题
// 1.创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { NSLog(@"发送请求");
[subscriber sendNext:@1]; return nil;
}]; // 2.创建连接
RACMulticastConnection *connect = [signal publish]; // 3.订阅信号,
// 注意:订阅信号,也不能激活信号,只是保存订阅者到数组,必须通过连接,当调用连接,就会一次性调用所有订阅者的sendNext:
[connect.signal subscribeNext:^(id x) { NSLog(@"订阅者一信号 %@",x); }]; [connect.signal subscribeNext:^(id x) { NSLog(@"订阅者二信号 %@",x); }]; // 4.连接,激活信号
[connect connect];
}
三、bind
// ReactiveCocoa核心方法bind
- (void)bind{
// 假设想监听文本框的内容,并且在每次输出结果的时候,都在文本框的内容拼接一段文字“输出:” // 方式一:在返回结果后,拼接。
[self.textField.rac_textSignal subscribeNext:^(id x) { NSLog(@"输出:%@",x);
}]; // map
[[_textField.rac_textSignal map:^id(id value) {
// 当源信号发出,就会调用这个block,修改源信号的内容
// 返回值:就是处理完源信号的内容。
return [NSString stringWithFormat:@"输出:%@",value];
}] subscribeNext:^(id x) { NSLog(@"%@",x);
}]; }
四、concat
// 操作方法组合
- (void)concat{
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; [subscriber sendCompleted]; return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil;
}]; // 把signalA拼接到signalB后,signalA发送完成,signalB才会被激活。
RACSignal *concatSignal = [signalA concat:signalB]; // 以后只需要面对拼接信号开发。
// 订阅拼接的信号,不需要单独订阅signalA,signalB
// 内部会自动订阅。
// 注意:第一个信号必须发送完成,第二个信号才会被激活
[concatSignal subscribeNext:^(id x) { NSLog(@"%@",x); }]; // concat底层实现:
// 1.当拼接信号被订阅,就会调用拼接信号的didSubscribe
// 2.didSubscribe中,会先订阅第一个源信号(signalA)
// 3.会执行第一个源信号(signalA)的didSubscribe
// 4.第一个源信号(signalA)didSubscribe中发送值,就会调用第一个源信号(signalA)订阅者的nextBlock,通过拼接信号的订阅者把值发送出来.
// 5.第一个源信号(signalA)didSubscribe中发送完成,就会调用第一个源信号(signalA)订阅者的completedBlock,订阅第二个源信号(signalB)这时候才激活(signalB)。
// 6.订阅第二个源信号(signalB),执行第二个源信号(signalB)的didSubscribe
// 7.第二个源信号(signalA)didSubscribe中发送值,就会通过拼接信号的订阅者把值发送出来. }
五、than
- (void)than{
// then:用于连接两个信号,当第一个信号完成,才会连接then返回的信号
// 注意使用then,之前信号的值会被忽略掉.
// 底层实现:1、先过滤掉之前的信号发出的值。2.使用concat连接then返回的信号
[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@1];
[subscriber sendCompleted];
return nil;
}] then:^RACSignal *{
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@2];
return nil;
}];
}] subscribeNext:^(id x) {
// 只能接收到第二个信号的值,也就是then返回信号的值
NSLog(@"%@",x);
}];
}
六、merge
- (void)merge{
// merge:把多个信号合并成一个信号
//创建多个信号
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@1];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@2];
return nil;
}];
// 合并信号,任何一个信号发送数据,都能监听到.
RACSignal *mergeSignal = [signalA merge:signalB];
[mergeSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 底层实现:
// 1.合并信号被订阅的时候,就会遍历所有信号,并且发出这些信号。
// 2.每发出一个信号,这个信号就会被订阅
// 3.也就是合并信号一被订阅,就会订阅里面所有的信号。
// 4.只要有一个信号被发出就会被监听。
}
七、zipWith
- (void)zipWith{
//zipWith:把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元组,才会触发压缩流的next事件。
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@1];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@2];
return nil;
}];
// 压缩信号A,信号B
RACSignal *zipSignal = [signalA zipWith:signalB];
[zipSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 底层实现:
// 1.定义压缩信号,内部就会自动订阅signalA,signalB
// 2.每当signalA或者signalB发出信号,就会判断signalA,signalB有没有发出个信号,有就会把最近发出的信号都包装成元组发出。
}
八、combineLatest
// combineLatest:将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号。
- (void)combineLatest{
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; return nil;
}]; RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil;
}]; // 把两个信号组合成一个信号,跟zip一样,没什么区别
RACSignal *combineSignal = [signalA combineLatestWith:signalB]; [combineSignal subscribeNext:^(id x) { NSLog(@"%@",x);
}]; // 底层实现:
// 1.当组合信号被订阅,内部会自动订阅signalA,signalB,必须两个信号都发出内容,才会被触发。
// 2.并且把两个信号组合成元组发出。 }
九、combineLatestReduce
// 组合并聚合
- (void)combineLatestReduce{
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; return nil;
}]; RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil;
}]; // 聚合
// 常见的用法,(先组合在聚合)。combineLatest:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock
// reduce中的block简介:
// reduceblcok中的参数,有多少信号组合,reduceblcok就有多少参数,每个参数就是之前信号发出的内容
// reduceblcok的返回值:聚合信号之后的内容。
RACSignal *reduceSignal = [RACSignal combineLatest:@[signalA,signalB] reduce:^id(NSNumber *num1 ,NSNumber *num2){ return [NSString stringWithFormat:@"%@ %@",num1,num2]; }]; [reduceSignal subscribeNext:^(id x) { NSLog(@"%@",x);
}]; // 底层实现:
// 1.订阅聚合信号,每次有内容发出,就会执行reduceblcok,把信号内容转换成reduceblcok返回的值。 }
iOS RAC常用方法的更多相关文章
- iOS UIView常用方法和属性
UIView常用方法 addSubView: // 添加子视图 insertSubview: atIndex // 视图插入到指定索引位置 insertSubview:aboveSubview: // ...
- IOS AppDelegate常用方法
// 当应用程序启动完毕的时候就会调用(系统自动调用) - (BOOL)application:(UIApplication *)application didFinishLaunchingWithO ...
- iOS Runtime常用方法整理
关于runtime的学习网上有很多博客,在学习之前也查过很多资料,觉得南峰子老师博客中对 runtime 的讲解挺详细的,博客地址:http://southpeak.github.io/categor ...
- iOS - runtime 常用方法举例说明
使用的自定义类,如下: #import <Foundation/Foundation.h> @interface Person : NSObject @property(nonatomic ...
- 4. iOS测试常用方法
1. [XCUIElement exists]方法只能确定这个View是否存在,即使不在当前屏幕上也返回True.如果要确定View是否在屏幕可见范围内,可以判断其Frame是否在Window的 ...
- iOS RAC使用补充
1 延迟执行 [[RACScheduler mainThreadScheduler] afterDelay: schedule:^{ NSLog(@"延迟执行.."); }]; ...
- iOS - NetRequest 网络数据请求
1.网络请求 1.1 网络通讯三要素 1.IP 地址(主机名): 网络中设备的唯一标示.不易记忆,可以用主机名(域名). 1) IP V4: 0~255.0~255.0~255.0~255 ,共有 2 ...
- ios实例开发精品文章推荐(7.23)
---------------------------------------------------------------------------------------------------- ...
- iOS单元測试:Specta + Expecta + OCMock + OHHTTPStubs + KIF
框架选择 參考这篇选型文章,http://zixun.github.io/blog/2015/04/11/iosdan-yuan-ce-shi-xi-lie-dan-yuan-ce-shi-kuang ...
随机推荐
- 线段树 Mayor's posters
甚至DFS也能过吧 Mayor's posters POJ - 2528 The citizens of Bytetown, AB, could not stand that the candidat ...
- 【2018.8.10】四连测day4 题解
T1:给出一棵 $n$ 个节点的无根树,其中 $m$ 个节点是特殊节点,求对于任意 $i ∈ [0, m]$,包含 $i$ 个特殊节点的联通块个数$\mod 998244353$. $1<=n, ...
- bzoj1975: [Sdoi2010]魔法猪学院【k短路&A*算法】
1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 2446 Solved: 770[Submit][Statu ...
- LINUX支持哪些文件系统
我们在Linux中常用的文件系统主要有ext3.ext2及reiserfs :Windows和Dos常用的文件系统是fat系列(包括fat16及fat32等)和ntfs 文件系统:光盘文件系统是ISO ...
- AC日记——美元汇率 洛谷 P1988
题目背景 此处省略maxint+1个数 题目描述 在以后的若干天里戴维将学习美元与德国马克的汇率.编写程序帮助戴维何时应买或卖马克或美元,使他从100美元开始,最后能获得最高可能的价值. 输入输出格式 ...
- js判断手机的横竖屏调整样式
在移动端,我们经常遇到横竖屏的问题,所以我们改如何判断或针对横竖屏来写代码呢.首先需要在head中加入如下代码: <meta name="viewport" content= ...
- CODEVS_1033 蚯蚓的游戏问题 网络流 最小费用流 拆点
原题链接:http://codevs.cn/problem/1033/ 题目描述 Description 在一块梯形田地上,一群蚯蚓在做收集食物游戏.蚯蚓们把梯形田地上的食物堆积整理如下: a(1,1 ...
- Word文档转Markdown插件(Windows)
在线的转换,Shell脚本的转换都试过了,都没有原生Word文档集成的插件转换这么好用,并且没有Bug. 下载:http://www.writage.com/
- Windows下拷贝Linux的文件到本地(Putty)
去官网下载的Putty中包含了如下文件: 其中pscp.exe是一个远程复制文件的工具. 官网:https://www.chiark.greenend.org.uk/~sgtatham/putty/l ...
- Spring的IoC容器-Spring ApplicationContext容器
Application Context是spring中较高级的容器.和BeanFactory类似,它可以加载配置文件中定义的bean,将所有的bean集中在一起,当有请求的时候分配bean. 另外,它 ...