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 ...
随机推荐
- 公钥密码之RSA密码算法大素数判定:Miller-Rabin判定法!
公钥密码之RSA密码算法大素数判定:Miller-Rabin判定法! 先存档再说,以后实验报告还得打印上交. Miller-Rabin大素数判定对于学算法的人来讲不是什么难事,主要了解其原理. 先来灌 ...
- BZOJ 4161 Shlw loves matrixI ——特征多项式
矩阵乘法递推的新姿势. 叉姐论文里有讲到 利用特征多项式进行递推,然后可以做到k^2logn #include <cstdio> #include <cstring> #inc ...
- [BZOJ4992] [Usaco2017 Feb]Why Did the Cow Cross the Road(spfa)
传送门 把每个点和曼哈顿距离距离它3步或1步的点连一条边,边权为3 * t + a[x][y] 因为,走3步,有可能是3步,也有可能是1步(其中一步拐了回来) 最后,把终点和曼哈顿距离距离它1步和2布 ...
- BZOJ 1260: [CQOI2007]涂色paint【区间DP】
Description 假设你有一条长度为5的木版,初始时没有涂过任何颜色.你希望把它的5个单位长度分别涂上红.绿.蓝.绿.红色,用一个长度为5的字符串表示这个目标:RGBGR. 每次你可以把一段连续 ...
- 【2018.11.23】2018WCTest(8)
T1 小 $X$ 无敌就是指他的防御 $\ge$ 怪物的攻击 $n$.另外小 $X$ 最多只需要把攻击加到怪物的防御 $k$,此时已经能一招秒一个,再多加必定无用且需承受更多伤害. $20$ 分 $d ...
- 【bzoj1483】[HNOI2009]梦幻布丁 set
[bzoj1483][HNOI2009]梦幻布丁 Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2 ...
- 窗口(codevs 4373)
题目描述 Description 给你一个长度为N的数组,一个长为K的滑动的窗体从最左移至最右端,你只能见到窗口的K个数,每次窗体向右移动一位,如下表: Window position Min val ...
- 【Codeforces Round #503 (Div. 2)】
A:https://www.cnblogs.com/myx12345/p/9843198.html B:https://www.cnblogs.com/myx12345/p/9843245.html ...
- 使用注解开发springmvc
1.导入jar包 commons-logging-1.2.jar spring-aop-4.3.6.RELEASE.jar spring-beans-4.3.6.RELEASE.jar spring- ...
- oracle分区表备份恢复
https://blog.csdn.net/jc_benben/article/details/51546815