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.不管订阅者是什么时候订阅的,发送者总是会把相同的消息发 ...
随机推荐
- Powershell 的自己主动部署
工作中反复性的版本号移植,一天上线10几次,让我痛不欲生,频繁的操作也可能出现疲劳性失误,导致严重的生产故障.于是乎,闲暇时间.我開始研究使用powershell自己主动部署程序到Linuxse ...
- Linux下安装subversion1.6.5和apache2
以下安装是在RHEL5.5默认安装的情况下,以root身份进行安装!这个实验我安装了n次,最后总是不成功,因为涉及到略多的软件和配置.下面是安装步骤和配置,自己记下来.希望给下次配置的时候不要像以前那 ...
- 在Delphi中编写res文件
delphiimagedosinterfaceborland脚本先用记事本编写一个rc的文件. 如内容为: _Comms RCData Comms.jpg Comms.jpg为图片名称, 然后在这个r ...
- MVC Razor与javascript混编(js中嵌入razor)
其中的关键是输出js上的纯文本内容,让浏览器解析为其中的js代码 <script> BUI.use('common/main',function(){ var conf ...
- PureMVC--一款多平台MVC框架
官网:http://puremvc.org/ 下载:https://github.com/PureMVC/puremvc-csharp-multicore-framework/tree/1.1.0 A ...
- 教您如何在Word的mathtype加载项中修改章节号
在MathType数学公式编辑器中,公式编号共有五部分内容:分别是章编号(Chapter Number).节编号(Section Number).公式编号(Equation Number).括号(En ...
- 怎样批量修改MathType公式格式
MathType是一款数学公式编辑器,我们在写论文的时候常常会遇到,但是有时由于公式的样式.大小和间隔等不符合论文要求,这个时候我们如果一个个修改是很麻烦的,还容易出错.所以批量修改就非常的有必要了, ...
- Win10关闭自动更新
1.搜索栏输入“组策略”后回车 2.找到计算机配置→管理模板→Windows组件→Windows更新 3.在右侧双击“配置自动更新”,然后选择“已启用”,在左下方下拉菜单中选择“2 - 通知下载并通知 ...
- 阿里巴巴Java开发规约插件-体验
插件有哪些功能? 阿里技术公众号于今年的2月9日首次公布<阿里巴巴Java开发规约>,瞬间引起全民代码规范的热潮,上月底又发布了PDF的终极版,大家踊跃留言,期待配套的静态扫描工具开放出来 ...
- linux--GCC简单用法
gcc是linux下最常用的一款c编译器,对应于CPP 有相应的g++工具,debug有gdb,只是还不会用. 个人感觉gcc确实是个好东西,完全可以直接在gedit下编程然后写个shell脚本用gc ...