一 导入ReactiveCocoa框架

通常都会使用CocoaPods(用于管理第三方框架的插件)帮助我们导入

podfile如果只描述pod 'ReactiveCocoa', '~> 4.0.2-alpha-1',会导入不成功 因为用到了swift的一些东西 需要在podfile加上use_frameworks,重新pod install 才能导入成功

ReactiveCocoa常见的一些类: RACSignal:信号类,一般表示将来有数据传递,只要有数据改变,信号内部接收到数据,就会马上发出数据。 1.信号类(RACSiganl),只是表示当数据改变时,信号内部会发出数据,它本身不具备发送信号的能力,而是交给内部一个订阅者去发出 2.默认一个信号都是冷信号,也就是值改变了,也不会触发,只有订阅了这个信号,这个信号才会变为热信号,值改变了才会触发。 3.如何订阅信号:调用信号RACSignal的subscribeNext就能订阅 简单使用: // 1.创建信号 RACSubscriber是订阅者 RACSignal racsignal = [RACSignal createSignal:^RACDisposable (id subscriber) { // 3.发送信号 [subscriber sendNext:@100]; return nil; }];

   //  2.订阅信号
[racsignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];

RACSubscriber:表示订阅者的意思用于发送一个信号,这是一个协议,不是一个类,只要遵守这个协议并且实现方法才能成为订阅者,通过create创建信号,都有一个订阅者,帮助他发送数据 RACDisposable:用于取消订阅者或者清理资源,当信号发送完成或者发送错误的时候就会自动触发取消订阅 使用场景:不想监听某个信号时候可以用他主动取消订阅信号 例如:

// 1.创建信号 RACSignal racsignal = [RACSignal createSignal:^RACDisposable (id subscriber) { // 3.发送信号 [subscriber sendNext:@100];

  // 订阅者subscriber不会被销毁永远不会取消订阅(在不主动取消的情况下)
_subscriber = subscriber;// _subscriber成员变量强引用一次
self.disposable = [RACDisposable disposableWithBlock:^{
NSLog(@"信号被取消订阅");
}];
return self.disposable;

}]; // 2.订阅信号 subscribeNext在函数内部创建订阅者 [racsignal subscribeNext:^(id x) { NSLog(@"%@",x); }];

// 取消订阅
[self.disposable dispose];

RACSubject:信号提供者,自己可以充当信号又可以发送信号 使用场景,通常用来代替代理,有了它就可以不用定义代理了。 RACReplaySubject:重复提供信号类 RACSubject的子类 RACReplaySubject和RACSubject的区别: RACReplaySubject可以先发送信号在订阅信号,RACSubject不可以。

RACSubject使用步骤: // 1.创建信号 [RACSubject subject],跟RACSiganl不一样,创建信号时没有block RACSubject *subject = [RACSubject subject];

// 2.订阅信号 - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock
// 返回的是订阅者

RACDisposable posable1 = [subject subscribeNext:^(id x) { NSLog(@"第一个订阅者%@",x); }]; RACDisposableposable2 = [subject subscribeNext:^(id x) { NSLog(@"第二个订阅者%@",x); }];

// RACSubject:底层实现和RACSignal不一样。
// 1.调用subscribeNext订阅信号,只是把订阅者保存起来,并且订阅者的nextBlock已经赋值了。
// 2.调用sendNext发送信号,遍历刚刚保存的所有订阅者,一个一个调用订阅者的nextBlock。 //3.发送信号 sendNext:(id)value
[subject sendNext:@100];
[posable1 dispose];// 取消订阅信号
[subject sendNext:@100];

RACReplaySubject:使用步骤 RACReplaySubject *subjest = [RACReplaySubject subject];

//2.调用subscribeNext订阅信号,遍历保存的所有值,一个一个调用订阅者的nextBlock
RACDisposable *posable1 = [subjest subscribeNext:^(id x) {
NSLog(@"第一个订阅者%@",x);
}]; RACDisposable *posable2 = [subjest subscribeNext:^(id x) {
NSLog(@"第二个订阅者%@",x);
}];
//调用sendNext发送信号,把值保存起来,然后遍历刚刚保存的所有订阅者,一个一个调用订阅者的nextBlock
[subjest sendNext:@100];
[posable1 dispose];// 取消订阅 [subjest sendNext:@120];

RAC中的 集合类 RACTuple:元组类,类似NSArray,用来包装值

RACSequence:Rac中的集合类,用于代替NSArray,NSDictionary,可以使用它来快速遍历数组和字典 RACSequence使用场景:字典转模型

RACTuple简单使用: // 将数组转换层一个元组 RACTuple RACTuple tuple = [RACTuple tupleWithObjectsFromArray:@[@"1",@"2",@3,@4,@5]]; // 将元组转换为rac中的集合类RACSequence RACSequencesequence = tuple.rac_sequence; // 在将集合类(RACSequence)转换为信号(RACSignal) RACSignal *signal = sequence.signal; // 订阅信号,激活信号,会自动把集合中的所有值,遍历出来 [signal subscribeNext:^(id x) { NSLog(@"%@",x); }];

//可以链式调用
[tuple.rac_sequence.signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];

遍历字典: NSDictionary dict = @{@"name":@"程倩",@"age":@"26",@"sex":@"男"}; // 遍历字典 [dict.rac_sequence.signal subscribeNext:^(RACTuple x) {

    NSString *key = x[0];
NSString *value = x[1];
NSLog(@"%@ %@",key,value); }];

第二种遍历方式: NSDictionary dict = @{@"name":@"程倩",@"age":@"26",@"sex":@"男"}; // 遍历字典 [dict.rac_sequence.signal subscribeNext:^(RACTuple x) {

    // RACTupleUnpack  相当于 NSString *key = x[0];
// NSString *value = x[1];
RACTupleUnpack(NSString *key,NSString *value) = x;
NSLog(@"%@ %@",key,value); }];

字典转模型: NSString filePath = [[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil]; NSArraydictArr = [NSArray arrayWithContentsOfFile:filePath]; NSMutableArray *flags = [NSMutableArray array]; _flags = flags;

// rac_sequence注意点:调用subscribeNext,并不会马上执行nextBlock,而是会等一会。
[dictArr.rac_sequence.signal subscribeNext:^(id x) {
// 运用RAC遍历字典,x:字典
FlagItem *item = [FlagItem flagWithDict:x];
[flags addObject:item];
}]; // 3.3 RAC高级写法:
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil]; NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];
// map:映射的意思,目的:把原始值value映射成一个新值
// array: 把集合转换成数组
// 底层实现:当信号被订阅,会遍历集合中的原始值,映射成新值,并且保存到新的数组里。
NSArray *flags = [[dictArr.rac_sequence map:^id(id value) {
return [FlagItem flagWithDict:value];
}] array];

ReactiveCocoa开发中常见用法:

1.代替代理 rac_signalForSelector:用于替代代理 //rac_signalForSelector:将某个select转换为一个信号,然后订阅这个信号,系统调用这个函数的时候会发出信号 // 可以用来代替代理(但是不能传值)如果想传值使用RACSubject [[self rac_signalForSelector:@selector(didReceiveMemoryWarning)] subscribeNext:^(id x) { NSLog(@"系统调用了didReceiveMemoryWarning函数"); }];

  1. 代替KVO: rac_valuesAndChangesForKeyPath:用于监听某个对象的属性改变 // 代替KVO监听属性的改变这个函数需要导入NSObject+RACKVOWrapper.h头文件,这个文件默认没有导入 [self rac_observeKeyPath:@"name" options:NSKeyValueObservingOptionNew observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {

    NSLog(@"rac_observeKeyPath监听到值改变了");

    }]; //也可以将值改变转换为一个信号 然后订阅这个信号 [[self rac_valuesForKeyPath:@"name" observer:nil] subscribeNext:^(id x) { NSLog(@"rac_valuesForKeyPath监听到值改变了"); }]; 3.监听事件: rac_signalForControlEvents:用于监听某个事件 //监听按钮点击事件,返回一个信号,然后直接订阅这个信号 [[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) { NSLog(@"按钮被点击了"); }]; 4.代替通知 rac_addObserverForName:用于监听某个通知 // 代替通知中心 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"通知名称" object:nil] subscribeNext:^(id x) { NSLog(@"收到通知"); }]; [[NSNotificationCenter defaultCenter] postNotificationName:@"通知名称" object:nil];

  1. 监听文本框文字改变 rac_textSignal:只要文本框发出改变就会发出这个信号 // 监听文本框值的改变 [[self.textfield rac_textSignal] subscribeNext:^(id x) { NSLog(@"%@",x);//x是文本框中的值 }];

  2. 处理当界面有多次请求时,需要都获取到数据时,才能展示界面(两个信号都发送的 时候才会调用最后的select) // 6.处理多个请求,都返回结果的时候,统一做处理. RACSignal request1 = [RACSignal createSignal:^RACDisposable (id subscriber) { // 发送请求1 [subscriber sendNext:@"发送请求1"]; return nil; }];

    RACSignal request2 = [RACSignal createSignal:^RACDisposable (id subscriber) { // 发送请求2 [subscriber sendNext:@"发送请求2"]; return nil; }]; // 使用注意:几个信号,参数一的方法就几个参数,每个参数对应信号发出的数据。 [self rac_liftSelector:@selector(updateUIWithR1:r2:) withSignalsFromArray:@[request1,request2]];

ReactiveCocoa常见宏

1.RAC(TARGET, [KEYPATH, [NIL_VALUE]]):用于给某个对象的某个属性绑定。 // 只要文本框中的文字改变就会修改lable中的文字 RAC(self.label,text) = self.textfield.rac_textSignal; 2.RACObserve(self, name):监听某个对象的某个属性,返回的是信号。 //RACObserve 监听某个对象的某个值,返回的是一个信号,其实就是ac_valuesForKeyPath函数 [RACObserve(self, name) subscribeNext:^(id x) {

    NSLog(@"%@",x);
}];
  1. @weakify(Obj)和@strongify(Obj),一般两个都是配套使用,解决循环引用问题. @weakify(self);// 将self转换成弱指针引用 RACSignal signal = [RACSignal createSignal:^RACDisposable (id subscriber) {

    @strongify(self) // 将self转换为强指针引用,只在当前block中有效
    
    NSLog(@"%@",self);
    
    return nil;

    }]; _signal = signal;

4.RACTuplePack:把数据包装成RACTuple(元组类) // 把参数中的数据包装成元组 RACTuple *tuple = RACTuplePack(@10,@20);

5.RACTupleUnpack:把RACTuple(元组类)解包成对应的数据。 // 把参数中的数据包装成元组 RACTupletuple = RACTuplePack(@"xmg",@20); // 解包元组,会把元组的值,按顺序给参数里面的变量赋值 // name = @"xmg" age = @20 RACTupleUnpack(NSString name,NSNumber *age) = tuple;

RACMulticastConnection:当一个信号被多次订阅的时候,为了保证创建信号时避免多次调用创建信号中的block造成副作用可以使用RACMulticastConnection RACMulticastConnection通过RACSignal的-publish或者-muticast:方法创建

简单使用: // RACMulticastConnection使用步骤: // 1.创建信号 + (RACSignal )createSignal:(RACDisposable (^)(id subscriber))didSubscribe // 2.创建连接 RACMulticastConnection *connect = [signal publish]; // 3.订阅信号,注意:订阅的不在是之前的信号,而是连接的信号。 [connect.signal subscribeNext:nextBlock] // 4.连接 [connect connect]

// RACMulticastConnection底层原理:
// 1.创建connect,connect.sourceSignal -> RACSignal(原始信号) connect.signal -> RACSubject
// 2.订阅connect.signal,会调用RACSubject的subscribeNext,创建订阅者,而且把订阅者保存起来,不会执行block。
// 3.[connect connect]内部会订阅RACSignal(原始信号),并且订阅者是RACSubject
// 3.1.订阅原始信号,就会调用原始信号中的didSubscribe
// 3.2 didSubscribe,拿到订阅者调用sendNext,其实是调用RACSubject的sendNext
// 4.RACSubject的sendNext,会遍历RACSubject所有订阅者发送信号。
// 4.1 因为刚刚第二步,都是在订阅RACSubject,因此会拿到第二步所有的订阅者,调用他们的nextBlock // 需求:假设在一个信号中发送请求,每次订阅一次都会发送请求,这样就会导致多次请求。
// 解决:使用RACMulticastConnection就能解决. // RACMulticastConnection:解决重复请求问题
// 1.创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"发送请求");
[subscriber sendNext:@1];
return nil;
}]; // 2.创建连接
RACMulticastConnection *connect = [signal publish]; // 3.订阅信号,
// 注意:订阅信号,也不能激活信号,只是保存订阅者到数组,必须通过连接,当调用连接,就会一次性调用所有订阅者的sendNext:
[connect.signal subscribeNext:^(id x) {
NSLog(@"订阅者一信号");
}];
[connect.signal subscribeNext:^(id x) {
NSLog(@"订阅者二信号");
}];
// 4.连接,激活信号
[connect connect];

RACCommand:Rac中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递包装到这个类中,可以很方便的监听事件的执行过程。

使用场景:监听按钮点击和网络请求。 // RACCommand:处理事件 // RACCommand:不能返回一个空的信号,会闪退 // 创建命令 RACCommand command = [[RACCommand alloc]initWithSignalBlock:^RACSignal (id input) { // 当前block执行命令的时候调用 // input 执行命令传入参数 NSLog(@"%@",input); return [RACSignal createSignal:^RACDisposable (id subscriber) { [subscriber sendNext:@"执行命令产生数据"]; return nil; }]; }]; // 如果要拿到执行命令产生的数据,执行命令返回一个信号,直接订阅信号 RACSignal signal = [command execute:@1]; // 订阅信号 [signal subscribeNext:^(id x) { NSLog(@"%@",x); }];

executionSignals:信号中的信号,发送的数据就是信号

//executionSignals:信号中的信号,发送的数据就是信号 // 订阅信号,必须要在执行命令之前订阅 [command.executionSignals subscribeNext:^(RACSignal *x) { [x subscribeNext:^(id x) { NSLog(@"%@",x); }]; }]; [command execute:@100];

switchToLatest:获取最新发送的信号,只能用于信号中信号

// switchToLatest获取最新发送的信号,只能用于信号中信号 // 获取到最新发送的信号直接订阅 [command.executionSignals.switchToLatest subscribeNext:^(id x) { NSLog(@"%@",x); }]; [command execute:@100];

监听任务是否执行完毕:

RACCommand command = [[RACCommand alloc]initWithSignalBlock:^RACSignal (id input) { NSLog(@"执行命令传入参数%@",input);

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

      [subscriber sendNext:@"执行命令产生数据"];
// 发送完成
[subscriber sendCompleted];
return nil;
}];

}];

// 监听任务是否执行完成
[command.executing subscribeNext:^(id x) {
if([x boolValue]==YES)
{
NSLog(@"当前任务正在执行");
}else{
NSLog(@"当前任务执行没有在执行");
}
}]; [command execute:@0];

ReactiveCocoa基础和一些常见类介绍的更多相关文章

  1. ReactiveCocoa常见操作方法介绍/MVVM架构思想

      1.ReactiveCocoa常见操作方法介绍. 1.1 ReactiveCocoa操作须知 所有的信号(RACSignal)都可以进行操作处理,因为所有操作方法都定义在RACStream.h中, ...

  2. Java基础-JAVA中常见的数据结构介绍

    Java基础-JAVA中常见的数据结构介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是数据结构 答:数据结构是指数据存储的组织方式.大致上分为线性表.栈(Stack) ...

  3. ReactiveCocoa基础知识内容

    本文记录一些关于学习ReactiveCocoa基础知识内容,对于ReactiveCocoa相关的概念如果不了解可以网上搜索:RACSignal有很多方法可以来订阅不同的事件类型,ReactiveCoc ...

  4. ReactiveCocoa基础

    在讲ReactiveCocoa之前,我们来回忆一下Block在开发中的使用场景: 1.把block保存到对象中,等到恰当的时候才去调用 2.把block当做方法的参数使用,外界不调用,都是方法内部去调 ...

  5. Nmap扫描教程之网络基础服务DHCP服务类

    Nmap扫描教程之网络基础服务DHCP服务类 Nmap网络基础服务 网络基础服务是网络正常工作的基石,常见的网络基础服务包括DHCP服务和DNS服务.其中,DHCP服务用来为计算机动态分配IP地址:D ...

  6. CYQ.Data.Orm.DBFast 新增类介绍(含类的源码及新版本配置工具源码)

    前言: 以下功能在国庆期就完成并提前发布了,但到今天才有时间写文介绍,主要是国庆后还是选择就职了,悲催的是上班的地方全公司都能上网,唯独开发部竟不让上网,是个局域网. 也不是全不能上,房间里有三台能上 ...

  7. Java基础笔记 – Annotation注解的介绍和使用 自定义注解

    Java基础笔记 – Annotation注解的介绍和使用 自定义注解 本文由arthinking发表于5年前 | Java基础 | 评论数 7 |  被围观 25,969 views+ 1.Anno ...

  8. Object类介绍

    一.Object类介绍

  9. windows下mongodb基础玩法系列一介绍与安装

    windows下mongodb基础玩法系列 windows下mongodb基础玩法系列一介绍与安装 windows下mongodb基础玩法系列二CURD操作(创建.更新.读取和删除) windows下 ...

随机推荐

  1. 自制IPsec_vpn综合实验

    实验需求 R1.R2间tunnel建立私网: Vpn网关间配置ipsec实现数据加密: 使用tunnel模式下的ESP包头封装: 使用3des加密算法,md5摘要算法: 设置NAT旁路绕行流量: 利用 ...

  2. 8个超震撼的HTML5和纯CSS3动画源码

    HTML5和CSS3之所以强大,不仅因为现在大量的浏览器的支持,更是因为它们已经越来越能满足现代开发的需要.Flash在几年之后肯定会消亡,那么HTML5和CSS3将会替代Flash.今天我们要给大家 ...

  3. Swing-JComboBox用法-入门

    JComboBox是Swing中的下拉菜单控件.它永远只能选中一个项目,然而比单选按钮节省空间.如果使用setEditable设置为true则内部选项的文本可以编辑,因此这种组件被称为组合框.注意,对 ...

  4. 201521123119《Java程序设计》第10周学习总结

    1. 本周学习总结 Q1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 Q1.finally 题目4-2 Q1.1 截图你的提交结 ...

  5. java课程设计-猜数游戏

    1. 团队名称.团队成员介绍 团队名称:breeze 团队成员 组长:网络1514张朝玮 201521123106 组员:网络1513侯帅军 201521123092 2. 项目git地址 https ...

  6. 纳税服务系统【统计图Fusionchart】

    需求 我们在投诉模块中还有一个功能没有实现: 统计:根据年度将相应年度的每个月的投诉数进行统计,并以图表的形式展示在页面中:在页面中可以选择查看当前年度及其前4年的投诉数.在页面中可以选择不同的年度, ...

  7. jmeter 分布式实战

    最近作者在公司部署公司的分布式压力测试情况的时候,遇到了问题,什么问题呢,各种错误,于是大晚上的为了不耽误压测,我们就两个同事两台电脑搞,可是还是不行的呢,我要研究研究这个是什么梗,于是乎,大晚上加班 ...

  8. [转]IOS开发中的CGFloat、CGPoint、CGSize和CGRect

    http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CGGeometry/Reference ...

  9. 笔记|《简明Python教程》:编程小白的第一本python入门书

    <简明Python教程>这本书是初级的Python入门教材,初级内容基本覆盖,对高级内容没有做深入纠结.适合刚接触Python的新手,行文比较简洁轻松,读起来也比较顺畅. 下面是我根据各个 ...

  10. mysql、mariadb安装和多实例配置

    本文目录:1. mysql单实例安装 1.1 rpm安装mysql 1.2 通用二进制包安装mysql 1.2.1 初始化数据库 1.2.2 安装后的规范化操作 1.3 编译安装 1.3.1 编译安装 ...