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.不管订阅者是什么时候订阅的,发送者总是会把相同的消息发 ...
随机推荐
- 【MYSQL】导入中文后乱码问题
http://fatkun.com/2011/05/mysql-alter-charset.html
- 使用 MVVMLight 绑定数据
如果你还不知道如何在VS中加入MVVMLight的引用,那么建议你先翻阅这篇文章:在VS中安装/使用 MVVMLight 这篇文章主要是介绍如何使用MVVMLight来绑定数据到界面中(View),以 ...
- 如何把he_llo wo_rld 变成 HeLlo WoRld
有人问如何把he_llo wo_rld 变成 HeLlo WoRld,估计应该是一道面试的基础题吧. 思路很多种,就看如何实现 思路一.先根据空格分隔,然后转大写,最后再拼接.代码如下 <?ph ...
- ios开发之--ios11适配:TableView的heightForHeaderInSection设置高度无效/UISearchBar消失
更新到ios11,然后使用x-code9运行项目,发现tableview的-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInS ...
- python2.0_s12_day12_html介绍
html 就像一个裸体的人css 就像是人穿的衣服js 就像是人做的动作一.网页文件HTML的构成 1.对应规则的选择,就如同我们写python时#!/usr/bin/env python3.5 这么 ...
- Centos下Nagios的安装与配置
一.Nagios简介 Nagios是一款开源的电脑系统和网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系统或服务状态异常时发出邮件或短信报 ...
- 复习前面一个月的学习C#感觉道路好艰难啊
今天是复习前面学习的内容,感觉这一个月来真的学习了很多,但是掌握的不好,好多都是在老师讲完课后做起来练习感觉这知识用起来蛮轻松地,但是经过昨天和今天的复习发现好多还是给忘记啦,甚是失落啊,刚开始就知道 ...
- HTTP/2笔记之连接建立
前言 HTTP/2协议在TCP连接之初进行协商通信,只有协商成功,才会涉及到后续的请求-响应等具体的业务型数据交换. HTTP版本标识符 h2,基于TLS之上构建的HTTP/2,作为ALPN的标识符, ...
- 设计模式之模板方法模式(Java实现)
"那个,上次由于我老婆要给我做饭,所以就没有说完就走掉了...这个那个".这次和以前一样,先来开场福利(工厂方法模式已被作者踹下场).由美女抽象工厂介绍一下适用场景~大家欢迎 抽象 ...
- 关于Memcached反射型DRDoS攻击分析
一.Memcached反射攻击原理 1.反射DRDoS攻击: DRDoS攻击时DoS攻击的一种,DoS是指通过发送或引发大量的资源消耗导致服务不可用的一种攻击方式,中文称之为拒绝服务攻击.DRDoS是 ...