iOS 开发之 ReactiveCocoa(进阶)

Map : 映射

UITextField *textField =[[UITextField alloc]initWithFrame:CGRectMake(100, 100, 100, 40)];

textField.backgroundColor =[UIColor redColor];

[self.view addSubview:textField];

[[textField.rac_textSignal map:^id(NSString * value) {

return @(value.length);

}] subscribeNext:^(NSNumber * x) {

NSLog(@"%@",x);

}];

输入Ricky:

结果:

filter: 过滤

//只有当text.length>3的时候才会订阅改消息

[[textField.rac_textSignal filter:^BOOL(NSString * text) {

return text.length>3;

}] subscribeNext:^(id x) {

NSLog(@"%@",x);

}];

同样输入Ricky结果就是:

delay:延时

//延时2秒发送消息

RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

[subscriber sendNext:@"Ricky"];

[subscriber sendCompleted];

return nil;

}] delay:2];

[signal subscribeNext:^(id x) {

NSLog(@"%@",x);

}];

startWith:在发送消息之前,先发送一个消息

RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

[subscriber sendNext:@"Ricky"];

[subscriber sendCompleted];

return nil;

}] startWith:@"RAC"];

[signal subscribeNext:^(id x) {

NSLog(@"%@",x);

}];

timeout :超时

//设置超时时间为2秒,当超过2秒还没有发送消息的时候,就不会发送了

RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

[[RACScheduler mainThreadScheduler] afterDelay:3 schedule:^{

[subscriber sendNext:@"Ricky"];

[subscriber sendCompleted];

}];

return nil;

}] timeout:2 onScheduler:[RACScheduler mainThreadScheduler]];

[signal subscribeNext:^(id x) {

NSLog(@"%@",x);

}];

take :发送多个消息的时候,取最前面的几条

 

RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

[subscriber sendNext:@"Ricky1"];

[subscriber sendNext:@"Ricky2"];

[subscriber sendNext:@"Ricky3"];

[subscriber sendNext:@"Ricky4"];

[subscriber sendCompleted];

return nil;

}] take:2];

[signal subscribeNext:^(id x) {

NSLog(@"%@",x);

}];

takelast :发送多个消息的时候,取最后面的几条

RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

[subscriber sendNext:@"Ricky1"];

[subscriber sendNext:@"Ricky2"];

[subscriber sendNext:@"Ricky3"];

[subscriber sendNext:@"Ricky4"];

[subscriber sendCompleted];

return nil;

}] takeLast:3];

[signal subscribeNext:^(id x) {

NSLog(@"%@",x);

}];

takeUntil: RACSignal (发送在takeUntil后面的信号完成前的消息)

// RAC这个消息是2秒后完成,所以Ricky1 Ricky2这两个消息是可以发送到 而3秒后的Ricky3 Ricky4就不会发送.

RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

[subscriber sendNext:@"Ricky1"];

[subscriber sendNext:@"Ricky2"];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

[subscriber sendNext:@"Ricky3"];

[subscriber sendNext:@"Ricky4"];

[subscriber sendCompleted];

});

[subscriber sendCompleted];

return nil;

}] takeUntil:[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

[subscriber sendNext:@"RAC"];

[subscriber sendCompleted];

});

return nil;

}]];

[signal subscribeNext:^(id x) {

NSLog(@"%@",x);

}];

takeWhileBlock :当takeWhileBlock返回YES的时候发送消息

RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

[subscriber sendNext:@"Ricky1"];

[subscriber sendNext:@"Ricky2"];

[subscriber sendNext:@"Ricky3"];

[subscriber sendNext:@"Ricky4"];

[subscriber sendCompleted];

return nil;

}] takeWhileBlock:^BOOL(id x) {

return YES;

}];

[signal subscribeNext:^(id x) {

NSLog(@"%@",x);

}];

skip: 跳过

//跳过前2次

RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

[subscriber sendNext:@"Ricky1"];

[subscriber sendNext:@"Ricky2"];

[subscriber sendNext:@"Ricky3"];

[subscriber sendNext:@"Ricky4"];

[subscriber sendCompleted];

return nil;

}] skip:2];

[signal subscribeNext:^(id x) {

NSLog(@"%@",x);

}];

skipWhileBlcok 和 skipUntilBlcok

  • skipWhileBlcok:当Block返回YES的时候跳过,返回No的时候发送.
  • skipUntilBlcok: skipUntilBlcok和skipWhileBlcok相反,当Block返回NO的时候跳
  • 过,返回YES的时候发送.

结合及时搜索优化

当我们在做及时搜索的时候,例如在UITextField中输入搜索内容,每当我们输入一个字符的时候当会请求服务器,无形中给服务器带来了很大的压力

UITextField *textField =[[UITextField alloc]initWithFrame:CGRectMake(100, 100, 100, 40)];

textField.backgroundColor =[UIColor redColor];

[self.view addSubview:textField];

[textField.rac_textSignal subscribeNext:^(NSString * text) {

NSLog(@"request--- %@",text);

}];

  • 优化请求时间间隔:throttle(节流)

throttle:设置一个间隔时间,当两次信号之间的时间差下于这个时间就不会发送请求

[[textField.rac_textSignal throttle:0.3] subscribeNext:^(NSString * text) {

NSLog(@"request--- %@",text);

}];

  • distinctUntilChanged: 优化请求字符一样的时候(当后一个请求和前一个请求一样的时候,就可以不用请求)

[[[textField.rac_textSignal throttle:0.3]distinctUntilChanged]

subscribeNext:^(NSString * text) {

NSLog(@"request--- %@",text);

}];

  • ignore :忽略某些 例如上面的空字符

[[[[textField.rac_textSignal throttle:0.3]distinctUntilChanged] ignore:@"" ]

subscribeNext:^(NSString * text) {

NSLog(@"request--- %@",text);

}];

  • switchToLatest :当你请求数据的时候,网络会有延迟,数据还没有返回回来,这时候你发送了新的请求,则我们取消前一次的请求,只发送最新的请求.

[[[[[[textField.rac_textSignal throttle:0.3]distinctUntilChanged] ignore:@"" ] map:^id(id value) {

return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

[subscriber sendNext:@"Request --- ricky"];

return nil;

}];

}] switchToLatest]

subscribeNext:^(NSString * text) {

NSLog(@"request--- %@",text);

}];

多个信号处理

 

RACSignal *singalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

[subscriber sendNext:@"singalA"];

[subscriber sendCompleted];

});

return nil;

}];

RACSignal *singalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

[subscriber sendNext:@"singalB"];

[subscriber sendCompleted];

});

return nil;

}];

merge: 同时订阅2个信号

[[singalA merge:singalB] subscribeNext:^(id x) {

NSLog(@"%@",x);

}];

singalA延迟2秒,singalB延迟5秒,她们相差了3秒.说明他们是同时发送的

concat

singalA完成后 才会订阅singalB 有点像串行队列 A失败了 B就不会被订阅

[[singalA concat:singalB] subscribeNext:^(id x) {

NSLog(@"%@",x);

}];

singalA延迟2秒,singalB延迟5秒,她们相差了5秒.说明A发送完,B才发送的.

zipWith和combineLatest:每个信号都至少要发送一次才可以被订阅.

 

[[singalA zipWith:singalB] subscribeNext:^(RACTuple * tuple) {

NSLog(@"%@",tuple);

}];

[[RACSignal combineLatest:@[singalA,singalB]] subscribeNext:^(RACTuple * tuple) {

NSLog(@"%@",tuple);

}];

RAC中的宏(结合例子)

  • UIButton中没有setbackgroundColor forstatus这个方法,使用RAC很简单实现

UIButton *button =[UIButton buttonWithType:UIButtonTypeCustom];

button.frame = CGRectMake(100, 100, 100, 100);

button.backgroundColor = [UIColor yellowColor];

[self.view addSubview:button];

RAC(button,backgroundColor) = [RACObserve(button, selected) map:^id(NSNumber * selected) {

return [selected boolValue]?[UIColor yellowColor]:[UIColor redColor];

}];

[[button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(UIButton * x) {

x.selected = !x.selected;

}];

  • RAC快速实现秒表

UILabel *lab =[[UILabel alloc]initWithFrame:CGRectMake(100, 100, 200, 50)];

lab.backgroundColor =[UIColor cyanColor];

[self.view addSubview:lab];

RAC(lab,text) = [[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]] map:^id(NSData * value) {

return value.description;

}];

时间: 2024-10-13 14:42:14

iOS 开发之 ReactiveCocoa(进阶)的相关文章

iOS开发之ReactiveCocoa下的MVVM(干货分享)

最近工作比较忙,但还是出来更新博客了,今天给大家分享一些ReactiveCocoa以及MVVM的一些东西,干活还是比较足的.在之前发表过一篇博文,名字叫做<iOS开发之浅谈MVVM的架构设计与团队协作>,大体上讲的就是使用Block回调的方式实现MVVM的.在写上篇文章时也知道有ReactiveCocoa这个函数响应式编程的框架,并且有许多人用它来更好的实现MVVM.所以在上篇博客发表后,有些同行给评论建议看一下ReactiveCocoa的东西,所以就系统的看了一下ReactiveCocoa的

iOS 开发之 ReactiveCocoa(基础)

前言 前段时间在看Masonry这个全新的第三方的布局框架的时候,开始了解了链式编程.后来慢慢的又开始了解函数式编程和响应式编程.在这集中的编程思想下,开始接触和研究了ReactiveCocoa这个框架.在很多大神的blog中,都对这个框架有着高度的评价,各种秀自己如何灵活的使用ReactiveCocoa.今天主要就是这个框架的一些自己的学习笔记. 1.ReactiveCocoa简介 ReactiveCocoa(简称为RAC),是由Github开源的一个应用于iOS和OS开发的新框架. Reac

iOS开发之ReactiveCocoa下的MVVM

最近工作比较忙,但还是出来更新博客了,今天给大家分享一些ReactiveCocoa以及MVVM的一些东西,干活还是比较足的.在之前发表过一篇博文,名字叫做<iOS开发之浅谈MVVM的架构设计与团队协作>,大体上讲的就是使用Block回调的方式实现MVVM的.在写上篇文章时也知道有ReactiveCocoa这个函数响应式编程的框架,并且有许多人用它来更好的实现MVVM.所以在上篇博客发表后,有些同行给评论建议看一下ReactiveCocoa的东西,所以就系统的看了一下ReactiveCocoa的

IOS开发之SWIFT进阶部分

概述 上一篇文章<iOS开发系列--Swift语言> 中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用Swift 进行iOS开发还是不够的.在这篇文章中将继续介绍一些Swift开发中一些不常关注但是又必备的知识点,以便对Swift有进一步的了解. 访问控制 Swift命名空间 Swift和ObjC互相调用 Swift和ObjC映射关系 Swift调用ObjC ObjC调用Swift 扩展—Swift调用C 反

iOS开发之MVVM在项目中的应用

今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦~). 由于本人项目经验有限,关于架构设计方面的东西理解有限,我个人对MVVM的理解主要是借鉴于之前的用过的MVC的Web框架~在学校的时候用过ThinkPHP框架,和SSH框架,都是MVC的架构模式,今天MVVM与传统的MVC可谓是极为相似,也可以说是兄弟关系,也就是一家人了. 说到架构设计和团队

李洪强IOS开发之-iOS经典面试题

李洪强IOS开发之-iOS经典面试题 写这篇文章的目的是因为前两天同学想应聘iOS开发,从网上找了iOS面试题和答案让我帮忙看看.我扫了一眼,倒吸了一口冷气,仔细一看,气的发抖.整篇题目30多个没有一个答案是对的,总结这篇面试题的作者对iOS机制根本就是一知半解就敢发到网上,不管有心还是无心都是坑害新人.所以在这里总结一下这几年面试别人和被别人面试遇到的一些我认为比较好的基础题目分享给大家,进阶题目在后续补充.我的理解如果有错漏请一定指出,非常感谢! 从12年开始做面试官到现在已经三个年头了,这

李洪强iOS开发之iOS好文章收集

李洪强iOS开发之iOS好文章收集 该文收集朋友们转发或自己的写的技术文章,如果你也有相关的好文章,欢迎留言,当好文章多的时候,我会对这些好文章进行分门别类 文章 简述 日期 直播服务配置 使用 nginx 和 rtmp 插件搭建视频直播和点播服务器 2015-05-12 20:13:00 iOS9适配技巧 图iOS9适配新技巧 2015-09-29 09:01 TextKit分页效果 图文混排 2015年6月1日 iPhone 6 / 6 Plus 设计·适配方案 屏幕适配 2014-11-2

IOS开发之copy的问题

copy的目的就是修改副本,修改原始对象和副本时不会产生干扰. 定义一个不可变属性A,再定义一个可变属性B.用B做添加删除等操作后再将B赋值给A时,有些人习惯用A = B:其实这样是不安全的. 假设有下面的一段代码: ? 1 2 3 4 5 6 7 8 9 10   int main() {    NSMutableString *strM = [NSMutableString [email protected]"123"];    NSString *str = strM;    N

iOS开发之WKWebView简单使用和常用使用场景

iOS开发之 WKWebVeiw使用 想用UIWebVeiw做的,但是突然想起来在iOS8中出了一个新的WKWebView,算是UIWebVeiw的升级版.本着对新事物的好奇,就上网查了一下,但是找了好多个都没说的多了详细,于是就问谷歌,找文档,看看使用方法,试用了一下,果然不错,记录下来,大家分享! WKWebView的特点: 性能高,稳定性好,占用的内存比较小, 支持JS交互 支持HTML5 新特性 可以添加进度条(然并卵,不好用,还是习惯第三方的). 支持内建手势, 据说高达60fps的刷