当前位置: 首页 > 编程日记 > 正文

好玩的 RAC

  1. UIControl

    • 监听 control 点击
    • 从此告别 addTarget 和 btnClick

      1
      2
      3
      4
      [[self.loginBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(UIButton *btn) {
      // btn, self.loginBtn
      // 这里执行点击之后的操作
      }];
  2. UITextField

    • 监听 textField 的 text 改变
    • 告别 UITextFieldDelegate

      1
      2
      3
      4
      5
      [self.myTF.rac_textSignal subscribeNext:^(NSString* text) {
      // text 即 self.myTF.text
      // 每当 text 有改变时,就会进入到这个 block
      }];
  3. UILabel

    • 把 label 的属性 text 绑定在 UITextField 上

      1
      2
      // self.myLab.text 随着 self.myTF.text 的改变而改变
      RAC(self.myLab, text) = self.myTF.rac_textSignal;
  4. 监听属性改变

    • 一旦 person 的 name 有变化,就进入 block 里面
    • 再不用写繁琐的 KVO

      1
      2
      3
      4
      [RACObserve(self.per, name) subscribeNext:^(NSString *name)
      {
      // name 即 self.per.name
      }];
  5. 监听通知信息

    • 一旦键盘 frame 有所变化,就进入 block 里面

    • 内部已经进行通知释放,不需要再 dealloc 中 移除

      1
      2
      3
      [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillChangeFrameNotification object:nil] subscribeNext:^(NSNotification *notification) {
      NSLog(@"-----%@", notification.description);
      }];
    • 发送通知还是之前的办法

      1
      [[NSNotificationCenter defaultCenter] postNotificationName:@"通知名称" object:nil];
  6. 数组

    • 遍历

      1
      2
      3
      4
      5
      NSArray *array = @[@1, @2, @3, @4, @5];
      [array.rac_sequence.signal subscribeNext:^(id x) {
      // x 即 数组 array 的元素
      }];
    • 过滤 filter,并获取过滤后的数组

      1
      2
      3
      NSArray *filter = [[array.rac_sequence filter:^BOOL(id value) {
      return [value integerValue] > 2;
      }] array];
    • 匹配、映射 map,变换元素并获取新数组

      1
      2
      3
      4
      5
      6
      7
      NSArray *map = [[array.rac_sequence map:^id(id value) {
      NSInteger a = [value integerValue] * [value integerValue];
      return [NSString stringWithFormat:@"%ld", a];
      }] array];
  7. 字典

    • rac_keySequence 和 rac_valueSequence 跟数组一样
    • rac_sequence 需要 RACTupleUnpack 解包

      1
      2
      3
      4
      5
      6
      NSDictionary *dic = @{@"name": @"lion", @"age": @18};
      [dic.rac_sequence.signal subscribeNext:^(id x) {
      RACTupleUnpack(NSString *key, NSString *value) = x;
      NSLog(@"\r\nkey: %@\r\nvalue: %@", key, value);
      }];
  8. 最经典的登录界面,登录按钮是否可点击

    • 先联合两个信号
    • 再解析信号结果
    • 最后把结果绑定到信号上

      1
      2
      3
      4
      5
      RAC(self.loginBtn, enabled) = [RACSignal
      combineLatest:@[self.usernameTF.rac_textSignal, self.passwordTF.rac_textSignal]
      reduce:^id(NSString *username, NSString *password){
      return @(username.length > 6 && password.length > 8);
      }];
  9. 节流 throttle

    • 表示 指定时间间隔内,不再发送信号
    • 这里添加 throttle, 表示在 0.5 秒内 text 没有改变时,才会进行搜索请求
    • 比如想搜索 reactiveCocoa,如果不添加 throttle,那么每输入一个字符,都会进行搜索请求,明显不是我们想要的。

      1
      2
      3
      4
      5
      [[[self.searchTF rac_textSignal]
      throttle:0.5]
      subscribeNext:^(id x) {
      NSLog(@"开始搜索请求==%@", x);
      }];
  10. 一通组合拳:

    1. 判断用户名是否符合规则,

    2. 用户名正确之后,进行判断密码是否符合规则

    3. 密码正确,进行请求验证,成功之后返回请求结果

    4. 返回主线程根据结果更新界面 UI

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// 1. 判断用户名
- (RACSignal *)validUsernameSignal {
// 防止循环引用
@weakify(self);
// 因为返回的是一个信号,所以需要创建
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
@strongify(self);
[[[[[self.usernameTF rac_textSignal]
// skip, 忽略,表示忽略几次信号
// 这里两次分别是,首次加载的时候,和 TF 第一次响应的时候,
// 可以把后面的 distinctUntilChanged 注释,测试下效果
skip:2]
// map, 变换,把信号内容的类型变换为另一种类型
// 把字符串根据长度转换为 bool 类型的对象
map:^id(NSString *value) {
return @(value.length > 5);
// distinctUntilChanged 只有值不同时,才会发送信号
// 这里为了防止,在值不满足/已满足 要求时,还继续发送信号
}] distinctUntilChanged]
// 这里订阅的信息,就是转换后的 bool 类型的对象,非 1 即 0
subscribeNext:^(id x) {
if ([x integerValue] == 1) {
[subscriber sendNext:@"用户名正确"];
[subscriber sendCompleted];
NSLog(@"-------用户名正确");
} else {
NSLog(@"-------用户名错误");
}
}];
return nil;
}];
}
// 3. 请求验证
- (RACSignal *)loginSuccessSignalWithPassword: (NSString *)psw {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
/**
* 这里可以进行请求验证用户名密码,并返回结果
*/
NSString *str = @"用户信息 Data";
NSLog(@"----登陆成功并返回用户信息 Data");
NSDictionary *dic = @{@"data": str};
[subscriber sendNext:dic];
[subscriber sendCompleted];
return nil;
}];
}
// 2、4、密码验证和界面更新
- (void)loginResult {
// 用户名的判断
[[[[[[[self validUsernameSignal]
// then, 只有前面的信号 发送信息,并完成才会继续
// 下面进行 密码的判断
then:^RACSignal *{
return self.passwordTF.rac_textSignal;
}]
// throttle,间隔 0.5 秒,
// 防止在输入密码过程中不断发送信号,优化性能
throttle:0.5]
// filter,过滤 ,只有符合要求的才能继续
filter:^BOOL(NSString *value) {
return [value length] > 6;
}]
// flattenMap 根据源信号的内容生成新的信号,后续订阅、监听的就是新信号的内容
// 常用于在信号嵌套中,处理信号中的信号
// 这里使用 flattenMap 生成新的信号,并且在信号内发送登录结果信息,以便后续传递信息
flattenMap:^RACStream *(NSString *value) {
return [self loginSuccessSignalWithPassword:value];
}]
// deliverOn 切换线程,
// RACScheduler, 即 RAC 中的多线程
// 切换为主线程
deliverOn:[RACScheduler mainThreadScheduler]]
// 订阅信号,获取信号传递的数据 data
subscribeNext:^(id x) {
NSLog(@"获取信息 \r\n%@,\r\n更新 UI", x);
}];
}

小结:

  • ReactiveCocoa 虽然说是思想上的巨大改变,但我更倾向于把它当做一种新型语法、更简便的语法来使用,在使用过程中,自然而然地就会体会它跟你以往编程的不同。使用多了,就会发现,原来这就是函数式响应式编程。

  • 语法上的使用,只是理解编程思想的入口,思想上的一小步才是编程上的一大步。

  • 理论是实践出来的,在你不懂理论的时候,那就赶紧实践吧。

相关文章:

机器学习简单代码示例

机器学习简单代码示例 //在gcc-4.7.2下编译通过。 //命令行&#xff1a;g -Wall -ansi -O2 test.cpp -o test #include <iostream> using namespace std; void input(int &oper,const bool meth) {//meth为true则只判断1&#xff0c;为false则判断1或0while(true){ci…

【2007-5】【素数算式】

Description 在下面的算式中每个“#”都表示一个素数数字。##* #————###请编写程序确定这些数字&#xff0c;输出所有的解。Input Output 依次打印输出每一种解&#xff0c;每行表示一种解&#xff0c;格式为&#xff1a;##*# ###。Sample Input Sample Output HINT Sou…

ubuntu服务器版编辑文件,Ubuntu 服务器版 18.04.4 固定 IP 设置

1、输入命令 su 以root用户权限操作2、找到Ubuntu网络配置文件vim /etc/netplan/50-cloud-init.yaml3、输入 i 让文件变成可编辑状态4、修改内容dhcp4: nodhcp4: noaddresses: [192.168.3.50/24]gateway4: 192.168.3.1nameservers:addresses: [8.8.8.8, 8.8.4.4]如图&#xff…

RACCommand 粗解

前言 学习 RAC 的过程中&#xff0c;RACCommand 是我一直很迷惑的点&#xff0c;感觉一直抓不到它的要点&#xff0c;不明白为何要这样使用。曾经想过用别的方法来替代&#xff0c;只要能找到替代的方法&#xff0c;暂时就没必要死磕&#xff0c;结果发现避免不了&#xff0c;那…

将整数拆分为2的幂次方

任意一个正整数都可以用2的幂次方表示&#xff0c;例如&#xff1a;137&#xff1d;2^72^32^0&#xff0c;同时约定次方用括号来表示&#xff0c;即a^b&#xff1d;a(b)。由此可知&#xff0c;137可表 示&#xff1a;2(7)2(3)2(0)。进一步&#xff1a;72^222^0(2^1用2表示)&…

vbs脚本在服务器上虚拟按键,iisvdir.vbs iis虚拟目录管理脚本使用介绍

IIS管理器也是通过调用iisvdir.vbs来实现虚拟目录的创建和删除的。我们可以通过命令行的方式来执行iisvdir.vbs脚本1)创建虚拟目录&#xff1a;cscript c:\windows\system32\iisvdir.vbs [/s server] [/u username /p password] /create [virtualRoot] Alias PhysicalPath2)删除…

Python字典部分源码分析,字典是无序的

1 def clear(self): # real signature unknown; restored from __doc__ 2 """ D.clear() -> None. Remove all items from D. """ 3 pass 1 #练习1、清空字典&#xff08;置空&#xff09; 2 li {"key1":"v…

【2011-3】【旋转表格】

Description 小敏是个数学迷&#xff0c;特别擅长加法与除法。老师给他一个问题&#xff0c;有一个22表格&#xff0c;表中有正整数A, B, C 和D&#xff0c;表格和表格值的计算如下&#xff1a;小敏的任务是对给出的表格每次顺时针旋转90度&#xff0c;使旋转后的表格值最大&am…

iOS-FXDanmaku弹幕库介绍、相关技术分享

前言 去年, 2016年, 一大波直播平台在移动端涌出, 直播慢慢步入了人们的视角. 网上如今能够看到各式各样的直播, 如秀场直播、游戏直播、体育直播、娱乐直播等等. 在各种类型的直播中, 弹幕在PC、移动端都几乎成为了标配, 今天在这里主要介绍一下个人开源的iOS弹幕, 以及提前为…

【廖雪峰Python学习笔记】字符串与编码

字符串与编码 三种字符编码 ASCII编码 &#xff1a;计算机由美国人发明&#xff0c;最早只有127个字符编码—— 大小写英文字母、数字和符号Unicode&#xff1a;把中文、日文、韩文等所有语言统一到一套编码中&#xff0c;2-4byte&#xff0c;现代OS和大多数语言都支持utf-8&a…

application

说明: 进行应用级操作.比如:设置提醒框,打开其他应用,显示联网状态,控制状态栏 单例对象, UIApplication *app[UIApplication sharedApplication];常用方法 方法1:设置app图标数字提示信息//设置app图标数字提示信息app.applicationIconBadgeNumber10;//ios8以后需要实现以下方…

博客园2013年4月份第2周源码发布详情

Silk Navigation for ASP.NET源码 2013-4-12 [VS2010]功能介绍&#xff1a;Silk Navigation 微软提供&#xff0c;为构建cross-browser 的Web应用程序&#xff0c;是用ASP.NET MVC3和jQuery的。它是非常简单使用ASP.NET Web窗体构建&#xff0c;从而在一个相当小的&#xff0c…

iOS 静态库封装

静态库和动态库 静态库和动态库存在形式 静态库&#xff1a;以.a 和 .framework为文件后缀名。动态库&#xff1a;以.tbd(之前叫.dylib) 和 .framework 为文件后缀名。 静态库和动态库的区别 静态库&#xff1a;链接时会被完整的复制到可执行文件中&#xff0c;被多次使用就有多…

【廖雪峰Python学习笔记】list tuple dict set

列表元组字典集合创建l [1, ‘a’, [1, 3], True]t (1, )d {‘key’ : ‘value’}s set([1, 2, 4, 2, 1])索引l[1]t[0]d.get(‘key’)/插入l.insert(1, ‘3’) / l.append(‘4’)/d[‘k1’] ‘v1’s.add(‘9’)修改l[0] 4/d[‘k1’] v/移除l.pop(0)/d.pop(‘k1’)s.remo…

响应式布局简明示例

响应式布局简明示例&#xff0c;响应式布局最好同时也是自适应布局&#xff0c;然后再配合css3媒体查询&#xff0c;来达到完美的响应式布局。css3的媒体查询ie9一下是不支持的&#xff0c;这太遗憾了&#xff0c;不过幸运的是有大神已经为前端屌丝们写好了用于IE9以下的媒体查…

iOS - APP任意push新页面那些事

大家都知道&#xff0c;UINavigationController对象有一个方法pushViewController&#xff0c;用来做视图跳转&#xff0c;也是在iOS开发中常用的页面转换方法之一。大多数APP的结构一般都是&#xff0c;使用一个UITabBarController&#xff0c;每个tab上都是一个UINavigationC…

主攻ASP.NET.4.5 MVC4.0之重生:Entity Framework生成实体类步骤(十三)

1.新建一个ASP.NET MVC 4.0 项目 2.安装Entity Framework Power Tools 3.Entity Framework- -RepositoryReverse Engineer Code First 4.Install-Package EntityFramework or Update-Package EntityFramework PM -Repository Install-Package EntityFramework 已安装“EntityFr…

【廖雪峰Python学习笔记】高阶函数

Higher-order function高阶函数映射过滤算法排序算法高阶函数 变量可指向函数 >>> abs # 函数 <built-in function abs> >>> abs(-0) # 函数调用 0 >>> func abs # 变量可指向函数 >>> func(-9) # 调用变量 调用函数 9函数名…

丁贵才130702010042第二次作业

第二次作业 2.9 设有如下语句&#xff0c;请用相应的谓词公式分别把它们表示出来&#xff1a; &#xff08;1&#xff09;有的人喜欢梅花&#xff0c;有的人喜欢菊花&#xff0c;有的人既喜欢梅花有喜欢梅花。 解&#xff1a;定义谓词 P&#xff08;x&#xff09;&#xff1a;x…

SpringMVC @RequestBody接收Json对象字符串

以前&#xff0c;一直以为在SpringMVC环境中&#xff0c;RequestBody接收的是一个Json对象&#xff0c;一直在调试代码都没有成功&#xff0c;后来发现&#xff0c;其实 RequestBody接收的是一个Json对象的字符串&#xff0c;而不是一个Json对象。然而在ajax请求往往传的都是Js…

【iOS】自定义日期选择器

自定义了一个日期选择器&#xff0c;与大家分享一下&#xff0c;期待宝贵建议。 github下载地址&#xff1a;https://github.com/huahua0809/XHDatePicker 下面只是说明一下怎么用&#xff0c;具体实现请下载代码看看&#xff1b; 如果大家觉得这个分享有所帮助的话&#xff0c…

【廖雪峰Python学习笔记】函数式编程

Functional Programming高阶函数返回函数匿名函数装饰器偏函数高阶函数 面向过程的程序设计&#xff1a; 把大段代码拆成函数&#xff0c;通过一层层函数调用&#xff0c;可将复杂任务分解成若干简单的任务函数是面向过程的程序设计的基本单位计算机Computer && 计算c…

asp 随机读取ID之Access

我在用ASP连接access 这个桌面数据库的时候&#xff0c;有时候要随机读取ID&#xff0c;传统的办法是&#xff1a; select top 3 * from tablename order by Rnd(ID) 但这样不行&#xff0c;默认还是按ID排序。 解决办法加上timer() 这个函数 select top 3 * from tablenam…

iOS Plist 文件的 增 删 改

一&#xff1a;Plist 文件的创建 Plist 文件作为我们IOS开发的一种数据存储文件&#xff0c;还是经常会用到的。在看《X-code江湖录》的时候&#xff0c;看到了这一点。自己就写了一下&#xff0c;把写的东西分享出来&#xff01;先看看它的创建&#xff0c;它的创建和我们其他…

Shine Button动画效果 类似Tinder APP的卡片界面

Shine Button动画效果--WCLShineButton 类似太阳动画的button FSPagerView 主要使用UICollectionView实现的优雅的屏幕幻灯片效果&#xff0c;主要用于Banner、产品展示、欢迎引导等。有Swift和OC两个版本。 folding-cell 一个可扩展的具有折叠效果的内容单元格 Cell折叠动效…

【廖雪峰Python学习笔记】面向对象编程OOP

面向对象编程 OOP&#xff1a;Object Oriented Programming程序的基本单元&#xff1a;对象 [ 数据 操作数据的函数] [属性 方法]三大特点&#xff1a;数据封装、继承和多态OPP中的计算机程序&#xff1a; 一系列命令的集合 —— 一组函数顺序执行。函数化大为小&#xff0…

基于 CoreText 实现的高性能 UITableView

来源&#xff1a;伯乐在线 - Hawk0620 如有好文章投稿&#xff0c;请点击 → 这里了解详情 如需转载&#xff0c;发送「转载」二字查看说明 引起UITableView卡顿比较常见的原因有cell的层级过多、cell中有触发离屏渲染的代码&#xff08;譬如&#xff1a;cornerRadius、maskTo…

.net程序员面试题

1&#xff0e; 在web页面中不论显示器的分辨率的大小是800600&#xff0c;还是1024768使得页面都显示在屏幕中间。 答&#xff1a;Margin:auto; 2&#xff0e; 请利用正则表达式验证一个字符串是否为数字串 &#xff08;请用csharp&#xff09;。 1 public static b…

Android深度探索与驱动开发(一)

Android移植可分为两个部分&#xff1a;应用移植和系统移植。应用移植是指将应用程序移植到某一特定硬件平台上。由于不同硬件平台之间的差异&#xff0c;Android SDK API也有可能存在差异&#xff0c;或者将应用程序从低版本Android移植到高版本的Android上。为了保证应用程序…

【廖雪峰Python学习笔记】面向对象高级编程

文章目录为实例和类绑定属性和方法\_\_slots__限制当前class实例&#xff0c;对子类不管用property装饰器&#xff0c;将getter方法变成属性多重继承 —— 一个子类可同时获得多个父类的所有功能[Mixin]定制类枚举类元类为实例和类绑定属性和方法 创建类 class Animal(object…