ReactiveCocoa 初学者使用
skip 跳过几个信号,不接受
filter :过滤
ignore:忽略某一个值
take:从开始一共取N次的信号
ignoreValues 这个比较极端,忽略所有值,只关心Signal结束,也就是只取Comletion和Error两个消息,中间所有值都丢弃
takeUntilBlock 对于每个next值,运行block,当block返回YES时停止取值
takeLast 取最后N次的信号,前提条件,订阅者必须调用完成,因为只有完成,就知道总共有多少信号
skipUntilBlock 同理,一直跳,直到block为YES
skipWhileBlock 一直跳,直到block为NO
1.信号量
_curTag=@"error";
@weakify(self)
//完整的创建RACSignal 包含三部分sendError(不一定要有) sendNext(可多个) sendCompleted(不一定要有)
//RACSubscriber:表示订阅者的意思,用于发送信号,这是一个协议,不是一个类,只要遵守这个协议,并且实现方法才能成为订阅者。通过create创建的信号,都有一个订阅者,帮助他发送数据
RACSignal *signal=[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
@strongify(self)
NSError *error;
if ([self.curTag isEqualToString:@"error1"]) {
error=[[NSError alloc]initWithDomain:@"myError" code:2001 userInfo:nil];
[subscriber sendError:error];
}
else
{
[subscriber sendNext:@"1"];
[subscriber sendNext:@"3"];
[subscriber sendNext:@"5"];
[subscriber sendCompleted];
}
return [RACDisposable disposableWithBlock:^{
NSLog(@"执行清理");
//RACDisposable:用于取消订阅或者清理资源,当信号发送完成或者发送错误的时候,就会自动触发它
//使用场景:不想监听某个信号时,可以通过它主动取消订阅信号
}];
}];
[signal subscribeNext:^(id x) {
NSLog(@"当前的值为:%@",x);
}];
[signal subscribeError:^(NSError *error) {
NSLog(@"当前出现错误%@",error);
}];
[signal subscribeNext:^(id x) {
NSLog(@"2当前的值为:%@",x);
}];
//输出
// 执行清理
// 当前出现错误Error Domain=myError Code=2001 "(null)"
// 执行清理
// 执行清理
//创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//发送信号
[subscriber sendNext:@"我是好人"];
[subscriber sendCompleted];
return nil;
}]; //订阅信号
[signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
上面的代码合成:
//创建信号
[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//发送信号
[subscriber sendNext:@"我是好人"];
[subscriber sendCompleted];
return nil;
}] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
运行结果

2.数组字典使用:
NSArray *array = @[@1,@2,@3];
[array.rac_sequence.signal subscribeNext:^(id x) {
//1
//2
//3
NSLog(@"%@",x);
}];
NSDictionary *dict = @{@"name":@"张三",@"age":@"20",@"sex":@"男"};
[dict.rac_sequence.signal subscribeNext:^(id x) {
// 解包元组,会把元组的值,按顺序给参数里面的变量赋值
// RACTupleUnpack这是个宏,后面会介绍
// name---张三
// age---20
// sex---男
RACTupleUnpack(NSString *key,NSString *value) = x;
NSLog(@"%@---%@",key,value);
//相当与
// NSString *key = x[0];
// NSString *value = x[1];
}];
//把NSArray通过rac_sequence方法生成RAC中的Sequence 获取该Sequence对象的信号量
RACSequence *sequence = [@[@"you", @"are", @"beautiful"] rac_sequence]; //调用Signal的Map方法,使每个元素的首字母大写
RACSignal *signal = sequence.signal; RACSignal *capitalizedSignal = [signal map:^id(NSString * value) {
return [value capitalizedString];
}]; // 通过subscribNext方法对其进行遍历输出
[signal subscribeNext:^(NSString * x) {
NSLog(@"signal --- %@", x);
}]; [capitalizedSignal subscribeNext:^(NSString * x) {
NSLog(@"capitalizedSignal --- %@", x);
}];
运行结果:

合并信号:
RACSubject *letters = [RACSubject subject];
RACSubject *numbers = [RACSubject subject];
RACSubject *chinese = [RACSubject subject]; [[RACSignal
merge:@[letters, numbers, chinese]]
subscribeNext:^(id x) {
NSLog(@"merge:%@", x);
}]; [letters sendNext:@"AAA"];
[numbers sendNext:@"666"];
[chinese sendNext:@"你好!"]; //AAA 666 你好!
组合信号:
RACSubject *letters = [RACSubject subject];
RACSubject *numbers = [RACSubject subject]; [[RACSignal
combineLatest:@[letters, numbers]
reduce:^(NSString *letter, NSString *number){
// reduce块中是合并规则:把numbers中的值拼接到letters信号量中的值后边。
return [letter stringByAppendingString:number];
}]
subscribeNext:^(NSString * x) {
NSLog(@"%@", x);
}]; [letters sendNext:@"A"];
[letters sendNext:@"B"];
[numbers sendNext:@"1"];
[letters sendNext:@"C"];
[numbers sendNext:@"2"]; //B1 C1 C2
信号开关:
//创建3个自定义信号
RACSubject *google = [RACSubject subject];
RACSubject *baidu = [RACSubject subject]; RACSubject *signalOfSignal = [RACSubject subject]; //获取开关信号
RACSignal *switchSignal = [signalOfSignal switchToLatest]; //对通过开关的信号量进行操作
[[switchSignal map:^id(NSString * value) {
return [@"https//www." stringByAppendingFormat:@"%@", value];
}] subscribeNext:^(NSString * x) {
NSLog(@"%@", x);
}]; //通过开关打开baidu
[signalOfSignal sendNext:baidu];
[baidu sendNext:@"baidu.com"];
[google sendNext:@"google.com"]; //通过开关打开google
[signalOfSignal sendNext:google];
[baidu sendNext:@"baidu.com/"];
[google sendNext:@"google.com/"];
代理:
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"RAC" message:@"RAC TEST" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"other", nil];
[[self rac_signalForSelector:@selector(alertView:clickedButtonAtIndex:) fromProtocol:@protocol(UIAlertViewDelegate)] subscribeNext:^(RACTuple *tuple) {
NSLog(@"%@",tuple.first);
NSLog(@"%@",tuple.second);
NSLog(@"%@",tuple.third);
}];
[alertView show];
字符串信号判断:
_input1 = @"2w435768";
[[RACObserve(self, input1)
filter:^(NSString* value){
if ([value hasPrefix:@"2"]) {
return YES;
} else {
return NO;
}
}]
subscribeNext:^(NSString* x){
NSLog(@"%@",x);
}];
监听textfield:
[[self.input.rac_textSignal
filter:^(NSString *str) {
if ([str hasPrefix:@"3545"]) {
return YES;
} else {
return NO;
}
}]
subscribeNext:^(NSString *str) {
NSLog(@"%@",str); }];
Button是否可用:
self.isConnected = [NSNumber numberWithBool:true];
RAC(self.loginBtn,enabled) = [RACSignal
combineLatest:@[self.name.rac_textSignal,
self.password.rac_textSignal,
RACObserve(self, isConnected)
]
reduce:^(NSString *price, NSString *name, NSNumber *connect){
return @(price.length > 0 && name.length > 0 && [connect boolValue]);
}
];
满足条件发送:
[[RACSignal
combineLatest:@[self.price.rac_textSignal,
self.name.rac_textSignal,
RACObserve(self, isConnected)
]
reduce:^(NSString *price, NSString *name, NSNumber *connect){
return @(price.length > 0 && name.length > 0 && ![connect boolValue]);
}]
subscribeNext:^(NSNumber *res){
if ([res boolValue]) {
NSLog(@"XXXXX send request");
}
}];
RACCommand使用
/**
// 1.signalBlock必须要返回一个信号,不能传nil.
// 2.如果不想要传递信号,直接创建空的信号[RACSignal empty];
// 3.RACCommand中信号如果数据传递完,必须调用[subscriber sendCompleted],这时命令才会执行完毕,否则永远处于执行中。
// 三、RACCommand设计思想:内部signalBlock为什么要返回一个信号,这个信号有什么用。
// 1.在RAC开发中,通常会把网络请求封装到RACCommand,直接执行某个RACCommand就能发送请求。
// 2.当RACCommand内部请求到数据的时候,需要把请求的数据传递给外界,这时候就需要通过signalBlock返回的信号传递了。
// 四、如何拿到RACCommand中返回信号发出的数据。
// 1.RACCommand有个执行信号源executionSignals,这个是signal of signals(信号的信号),意思是信号发出的数据是信号,不是普通的类型。
// 2.订阅executionSignals就能拿到RACCommand中返回的信号,然后订阅signalBlock返回的信号,就能获取发出的值。
*/
//1创建命令
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
//命令内部传递的参数
NSLog(@"input===%@",input);
//2.返回一个信号,可以返回一个空信号 [RACSignal empty];
return [RACSignal createSignal:^RACDisposable *(id subscriber) {
NSLog(@"发送数据");
//发送信号
[subscriber sendNext:@"22"];
// 注意:数据传递完,最好调用sendCompleted,这时命令才执行完毕。
[subscriber sendCompleted];
return nil;
}];
}];
//强引用
__command = command;
// 拿到返回信号方式二:
// command.executionSignals信号中的信号 switchToLatest转化为信号
[command.executionSignals.switchToLatest subscribeNext:^(id x) {
NSLog(@"拿到信号的方式二%@",x);
}];
//拿到返回信号方式一:
RACSignal *signal = [command execute:@"11"];
[signal subscribeNext:^(id x) {
NSLog(@"拿到信号的方式一%@",x);
}];
//3.执行命令
[command execute:@"11"];
//监听命令是否执行完毕
[command.executing subscribeNext:^(id x) {
if ([x boolValue] == YES) {
NSLog(@"命令正在执行");
}
else {
NSLog(@"命令完成/没有执行");
}
}];
// input===11
// 命令完成/没有执行
// 命令正在执行
// 发送数据
// 拿到信号的方式一22
// 拿到信号的方式二22
// 令完成/没有执行
通知:
首先,在某个页面中我们需要发出通知,这里就是最基本的通知的写法。发送名为postdata的通知并传送一个数组dataArray。 NSMutableArray *dataArray = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"postData" object:dataArray];
而在接受的页面我们需要增加观察者并接受数组,这时我们的RAC就派上用场了。 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"postData" object:nil] subscribeNext:^(NSNotification *notification) {
NSLog(@"%@", notification.name);
NSLog(@"%@", notification.object);
}];
kvo:
UIScrollView *scrolView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 200, 400)];
scrolView.contentSize = CGSizeMake(200, 800);
scrolView.backgroundColor = [UIColor greenColor];
[self.view addSubview:scrolView];
[RACObserve(scrolView, contentOffset) subscribeNext:^(id x) {
NSLog(@"success");
}];
ReactiveCocoa 初学者使用的更多相关文章
- ReactiveCocoa入门教程:第一部分
http://www.cocoachina.com/ios/20150123/10994.html 本文翻译自RayWenderlich,原文:ReactiveCocoa Tutorial--The ...
- [转]使用ReactiveCocoa实现iOS平台响应式编程
原文:http://www.itiger.me/?p=38 使用ReactiveCocoa实现iOS平台响应式编程 ReactiveCocoa和响应式编程 在说ReactiveCocoa之前,先要介绍 ...
- ReactiveCocoa 之 优雅的 RACCommand
RACCommand 是一个在 ReactiveCocoa 中比较复杂的类,大多数使用 ReactiveCocoa 的人,尤其是初学者并不会经常使用它. 在很多情况下,虽然使用 RACSignal 和 ...
- JavaScript进阶之路(一)初学者的开始
一:写在前面的问题和话 一个javascript初学者的进阶之路! 背景:3年后端(ASP.NET)工作经验,javascript水平一般般,前端水平一般般.学习资料:犀牛书. 如有误导,或者错误的地 ...
- iOS开发之ReactiveCocoa下的MVVM(干货分享)
最近工作比较忙,但还是出来更新博客了,今天给大家分享一些ReactiveCocoa以及MVVM的一些东西,干活还是比较足的.在之前发表过一篇博文,名字叫做<iOS开发之浅谈MVVM的架构设计与团 ...
- Python初学者之网络爬虫(二)
声明:本文内容和涉及到的代码仅限于个人学习,任何人不得作为商业用途.转载请附上此文章地址 本篇文章Python初学者之网络爬虫的继续,最新代码已提交到https://github.com/octans ...
- 给 DevOps 初学者的入门指南
当我们谈到 DevOps 时,可能讨论的是:流程和管理,运维和自动化,架构和服务,以及文化和组织等等概念.那么,到底什么是"DevOps"呢? 什么是DevOps 随着软件发布迭代 ...
- 一位资深程序员大牛给予Java初学者的学习路线建议
java学习这一部分其实也算是今天的重点,这一部分用来回答很多群里的朋友所问过的问题,那就是我你是如何学习Java的,能不能给点建议?今天我是打算来点干货,因此咱们就不说一些学习方法和技巧了,直接来谈 ...
- ReactiveCocoa 冷热订阅(cold subscribe, hot subscribe)
ReactiveCocoa支持两种订阅方式,一种是冷订阅,一种是热订阅. 热订阅的特点: 1.不管有没有消息订阅着,发送者总会把消息发出去. 2.不管订阅者是什么时候订阅的,发送者总是会把相同的消息发 ...
随机推荐
- Sharepoint 2013 Workflow Error
问题: (1)提示“reload the page and then start the workflow”错误 (2)提示“Unable to properly communicate with t ...
- 上千万或上亿数据(有反复),统计当中出现次数最多的N个数据. C++实现
上千万或上亿的数据,如今的机器的内存应该能存下.所以考虑採用hash_map/搜索二叉树/红黑树等来进行统计次数. 然后就是取出前N个出现次数最多的数据了,能够用第2题提到的堆机制完毕. #inclu ...
- Java集合----Set集合
Set集合 Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败. Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals 方法 Ha ...
- 处理URL为模块/控制器/方法的格式
一个路由在不确定长度的情况下,控制器和方法不一定传参进来,可能只有模块,甚至模块都没有,这个时候需要特殊处理一下,默认模块用 index,默认控制器用index,默认方法用 index来处理URL. ...
- linux连接sybase数据库-isql
转自:http://blog.knowsky.com/196438.htm 想要linux连接sybase数据库用命令isql: isql [-U login id] [-P password] [- ...
- JVM优化(一)-- 入门
一.JVM的概念 JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现 ...
- upper()
upper() 用于把字符串中的小写字母转换成大写字母 In [1]: str = "Hello World" In [2]: str.upper() Out[2]: 'HELLO ...
- Linux同步网络时间
1.date '+%Y%M%D' 按照格式显示当前日期,结果如下: [root@LAMP ~]# date "+%Y-%m-%d %H:%M:%S" -- :: 2.date -s ...
- Java自动类型转换
■ 自动类型转换:容量小的数据类型可以自动转换为容量大的数据类型. ■ 特例:可以讲整型常量直接赋给byte,short,char等类型变量,而不需要强制类型转换,只要不超出其表数范围. ■ 强制类型 ...
- JS 保存表单默认值 为空时自动填充默认值
var inputArray = document.getElementsByTagName("input"); var strArray = []; ; i < input ...