RAC 指的就是 RactiveCocoa ,是 Github 的一个开源框架,能够帮我们提供大量方便的事件处理方案,让我们更简单粗暴地去处理事件,现在分为 ReactiveObjC 和 ReactiveSwift ,两个框架的功能使用相似,由于正好在学习这个然后公司项目是用 OC 写的,所以将 ReactiveObjC 的使用方法记录一下。

ReactiveObjC 的使用

RAC 的核心思想:创建信号 - 订阅信号 - 发送信号 ,并且在 RAC 中我们会看到大量的 block ,所以在使用之前可以再重新温习一下 block 的使用。

1. RACSignal 信号

/* 创建信号 */
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
/* 发送信号 */
[subscriber sendNext:@"发送信号"]; return nil;
}]; /* 订阅信号 */
RACDisposable *disposable = [signal subscribeNext:^(id _Nullable x) {
NSLog(@"信号内容:%@", x);
}]; /* 取消订阅 */
[disposable dispose];

2. RACSubject 信号

和代理的用法类似,通常用来代替代理,有了它,就不必要定义代理了。

/* 创建信号 */
RACSubject *subject = [RACSubject subject]; /* 发送信号 */
[subject sendNext:@"发送信号"]; /* 订阅信号(通常在别的视图控制器中订阅,与代理的用法类似) */
[subject subscribeNext:^(id _Nullable x) { NSLog(@"信号内容:%@", x);
}];

3. RACTuple 元祖

RAC 的元祖,跟我们 OC 的数组其实是一样的,它其实就是封装了我们 OC 的数组。

/* 创建元祖 */
RACTuple *tuple = [RACTuple tupleWithObjects:@"", @"", @"", @"", @"", nil]; /* 从别的数组中获取内容 */
RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:@[@"", @"", @"", @"", @""]]; /* 利用 RAC 宏快速封装 */
RACTuple *tuple = RACTuplePack(@"", @"", @"", @"", @""); NSLog(@"取元祖内容:%@", tuple[]);
NSLog(@"第一个元素:%@", [tuple first]);
NSLog(@"最后一个元素:%@", [tuple last]);

4. 便利 Array 数组和 Dictionary 字典

可以省去使用 for 循环来遍历。

/* 遍历数组 */
NSArray *array = @[@"", @"", @"", @"", @""];
[array.rac_sequence.signal subscribeNext:^(id _Nullable x) {
NSLog(@"数组内容:%@", x); // x 可以是任何对象
}];
/* 遍历字典 */
NSDictionary *dictionary = @{@"key1":@"value1", @"key2":@"value2", @"key3":@"value3"};
[dictionary.rac_sequence.signal subscribeNext:^(RACTuple * _Nullable x) {
RACTupleUnpack(NSString *key, NSString *value) = x; // x 是一个元祖,这个宏能够将 key 和 value 拆开
NSLog(@"字典内容:%@:%@", key, value);
}];

下面两个方法都是将数组内容全部换为 0 ,第一个是单个操作,,第二个是一次性全部替换,两个方法都不会改变原数组内容,操作完后都会生成一个新的数组,省去了创建可变数组然后遍历出来单个添加的步骤。

/* 内容操作 */
NSArray *array = @[@"", @"", @"", @"", @""];
NSArray *newArray = [[array.rac_sequence map:^id _Nullable(id _Nullable value) {
NSLog(@"数组内容:%@", value);
return @""; // 将所有内容替换为 0
}] array];
/* 内容快速替换 */
NSArray *array = @[@"", @"", @"", @"", @""];
NSArray *newArray = [[array.rac_sequence mapReplace:@""] array]; // 将所有内容替换为 0

5. 监听 TextField 的输入改变

可以省去设置 delegate 和实现代理方法的步骤。

/* 监听 TextField 的输入(内容改变就会调用) */
[[textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"输入框内容:%@", x);
}];
/* 添加监听条件 */
[[textField.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
return value.length > ; // 表示输入文字长度 > 5 时才会调用下面的 block
}] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"输入框内容:%@", x);
}];

6. 监听 Button 点击事件

可以省去 addTarget 添加事件和创建方法的步骤。

[[button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
NSLog(@"%@ 按钮被点击了", x); // x 是 button 按钮对象
}];

7. 登录按钮状态实时监听

下面表示只有 用户名 和 密码 输入框内容都大于 0 时,登录 按钮才可以点击,而且状态是实时监听的,一句代码就能完成这个功能。

RAC(_loginButton, enabled) = [RACSignal combineLatest:@[_username.rac_textSignal, _password.rac_textSignal] reduce:^id _Nullable(NSString * username, NSString * password){
return @(username.length && password.length);
}];

8. 监听 Notification 通知事件

可省去在 -(void)dealloc {} 中清除通知和监听通知创建方法的步骤。

[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
NSLog(@"%@ 键盘弹起", x); // x 是通知对象
}];

9. 代替 Delegate 代理方法

可以省去监听以及设置 delegate 的步骤,下面表示只要 view 中执行了 btnClick 这个方法,就会发送信号执行这个回调。

[[view rac_signalForSelector:@selector(btnClick)] subscribeNext:^(RACTuple * _Nullable x) {
NSLog(@" view 中的按钮被点击了");
}];

10. 代替 KVO 监听

可以代替 KVO 监听,下面表示把监听 view 的 frame 属性改变转换成信号,只要值改变就会发送信号。

[[view rac_valuesForKeyPath:@"frame" observer:self] subscribeNext:^(id  _Nullable x) {
NSLog(@"属性的改变:%@", x); // x 是监听属性的改变结果
}];

还有一种更简单的写法,就是利用 RAC 的宏,和上面的效果是一样的。

[RACObserve(view, frame) subscribeNext:^(id  _Nullable x) {
NSLog(@"属性的改变:%@", x); // x 是监听属性的改变结果
}];

11. 代替 NSTimer 计时器

可以代替 NSTimer 使用。

@interface ViewController ()

@property (nonatomic, strong) RACDisposable *disposable;

@end
/* 定义计时器监听 */
self.disposable = [[RACSignal interval:1.0 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {
NSLog(@"当前时间:%@", x); // x 是当前的系统时间 /* 关闭计时器 */
[_disposable dispose];
}];

作者:Jonzzs
链接:https://www.jianshu.com/p/0845b1a07bfa
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

ReactiveObjC(RAC)的使用汇总的更多相关文章

  1. 11g RAC集群启动关闭、各种资源检查、配置信息查看汇总。

    简要:一:集群的启动与关闭 1. rac集群的手动启动[root@node1 bin]# ./crsctl start cluster -all2. 查看rac集群的状态[root@node1 bin ...

  2. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之集群概念介绍(一)

    集群概念介绍(一)) 白宁超 2015年7月16日 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习 ...

  3. Oracle 数据库知识汇总篇

    Oracle 数据库知识汇总篇(更新中..) 1.安装部署篇 2.管理维护篇 3.数据迁移篇 4.故障处理篇 5.性能调优篇 6.SQL PL/SQL篇 7.考试认证篇 8.原理体系篇 9.架构设计篇 ...

  4. Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之ORACLE集群概念和原理(二)

    ORACLE集群概念和原理(二) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  5. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 工作原理和相关组件(三)

    RAC 工作原理和相关组件(三) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  6. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之缓存融合技术和主要后台进程(四)

    缓存融合技术和主要后台进程(四) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  7. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 特殊问题和实战经验(五)

    RAC 特殊问题和实战经验(五) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  8. 【Oracle 集群】11G RAC 知识图文详细教程之RAC在LINUX上使用NFS安装前准备(六)

    RAC在LINUX上使用NFS安装前准备(六) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇 ...

  9. 【Oracle 集群】Oracle 11G RAC教程之集群安装(七)

    Oracle 11G RAC集群安装(七) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总. ...

随机推荐

  1. POJ 3046 Ant Counting ( 多重集组合数 && 经典DP )

    题意 : 有 n 种蚂蚁,第 i 种蚂蚁有ai个,一共有 A 个蚂蚁.不同类别的蚂蚁可以相互区分,但同种类别的蚂蚁不能相互区别.从这些蚂蚁中分别取出S,S+1...B个,一共有多少种取法. 分析 :  ...

  2. 牛客网 珂学送分( 期望DP )

    题意 : 题目链接 分析 : 听队友说一般概率从前往后推.期望从后往前推......... #include<bits/stdc++.h> using namespace std; ; d ...

  3. Internet History, Technology, and Security(week4)——History: Commercialization and Growth

    Explosive Growth of the Internet and Web: The Year of the Web 1994年后,由NCSA的老员工们构成的Netscape(网景)的成立.Ne ...

  4. 20181019-JSP 教程/简介

    JSP 教程 这是第一篇JSP JSP与PHP.ASP.ASP.NET等语言类似,运行在服务端的语言. JSP(全称Java Server Pages)是由Sun Microsystems公司倡导和许 ...

  5. [CSP-S模拟测试]:打扫卫生(暴力)

    题目描述 有$N$头奶牛,每头那牛都有一个标号$P_i1\leqslant Pi\leqslant M\leqslant N\leqslant 40,000$.现在$Farmer\  John$要把这 ...

  6. 如何删除eclipse的subclipse插件记住的SVN用户名和密码

    如何删除eclipse的subclipse插件记住的SVN用户名和密码找到auth目录,将其以及子目录.子文件都删除.路径在:C:\Users\Administrator\AppData\Roamin ...

  7. 《Vue前端开发手册》

    序言 为了统一前端的技术栈问题,技术开发二部规定开发技术必须以Vue为主. 为了更好的规范公司的前端框架,现以我前端架构师为主,编写以下开发规范,如有不当的地方,欢迎批评教育并慢慢改善该开发文档,谢谢 ...

  8. 如何将一个SpringBoot简便地打成一个war包(亲测有效)

    正常情况下SpringBoot项目是以jar包的形式,通过命令行: 来运行的,并且SpringBoot是内嵌Tomcat服务器,所以每次重新启动都是用的新的Tomcat服务器.正因如此,也出现了一个问 ...

  9. swiper(轮播)组件

    swiper是一个非常强大的组件 但是需要swiper-item这个标签来实现他想显示的内容 swiper-item标签有个item-id的属性,属性值:字符串 是swiper-item的标识符: 一 ...

  10. leetcode-mid-Linked list-328 Odd Even Linked List-NO

    mycode # Definition for singly-linked list. # class ListNode(object): # def __init__(self, x): # sel ...