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.不管订阅者是什么时候订阅的,发送者总是会把相同的消息发 ...
随机推荐
- 如何用ChemDraw建立多中心结构
通过调整ChemDraw多中心机构的连接可绘制有意义的络合物结构,建立中心原子和络合配体后,利用多中心化学键连接上述结构即可.以下内容将具体介绍如何用ChemDraw建立多中心结构. 一.多中心键和多 ...
- VC++ : VS2008 使用ATL开发COM组件
新建ATL Project,工程名命名为MyAtlCom: 出现工程 向导,一路“Next”: Add class,点击添加 ATL Simple Object , 类名CStatistic, 接口I ...
- 异常处理----使用 try…catch…finally 处理异常
使用 try…catch…finally 处理异常 异常处理是通过try-catch-finally语句实现的. try { ...... //可能产生异常的代码 } catch( Exception ...
- python2.0_s12_day9_mysql操作
mysql的基本语法: 1.数据库操作 show databases; create database 数据库名;如果想允许数据库可以写中文create database 数据库名 charset u ...
- React如何进行事件传参
今天在学习React的es6语法的时候,发现了个有趣的现象,就是this的指向问题.es6的this不同于es5,它在创立函数伊始便已经存在了,而不是像es5一样,睡调用的函数,this指向谁.但是这 ...
- 详解Integer.toString(int i)方法和String.valueOf(int i)方法
通过查看String类的源码: public static String valueOf(int i) { return Integer.toString(i); } 我们可以看到,String.va ...
- jQuery子页面获取父页面元素
$("input[type='checkbox']:checked",window.opener.document);//适用于打开窗口的父页面元素获取 $("input ...
- printf如何输出64位整数
From: http://blog.csdn.net/zzqhost/article/details/6064886 关于printf函数输出64位数的问题,其实在window下和linux下是不一样 ...
- delphi 获取本机IP地址和MAC地址
unit NetFunc; interface uses SysUtils, Windows, dialogs, winsock, Classes, ComObj, WinInet, Variants ...
- redis基础----->redis的基本使用(一)
这里我们就在虚拟机中安装redis,并且使用java和python实现简单的操作.深情是我承担不起的重担,情话只是偶尔兑现的谎言. redis的使用 下载地址:https://redis.io/.安装 ...