iOS RAC 学习笔记(主要是用法)
2021-03-28 本文已影响0人
鱼_446b
简介
RAC里面万物皆信号,对kvo、代理、通知、tagert、timer进行了封装。是我们的代码看上去更加紧凑。使用起来也更加方便
操作步骤总共三步
创建信号 (RACSignal)
订阅信号(RACSubject)相当于代理,可以获取信号和发送信号
发送信号 - (void)sendNext:(id)value
使用方法: 首先导入#import <ReactiveObjC.h>
常见用法:
可以完成那些功能:
1.监听按钮的点击事件, 以前用block或者tag,用RAC后,任意界面和类的按钮都可以一步监听到.
2.代替代理,比如在vc里面实现person类中的一个吃饭的方法,也是可以直接一步到位
3.监听属性改变,,比如界面1要监听到界面2的属性改变,之前要用kvo来实现,还得delloc,现在直接监听属性改变一步到位
4.代替通知,比如监听键盘弹出通知,一句代码搞定
5.监听文本框文字改变,之前要用一个代理,现在直接监听,时时改变的情况都可以输出
6.处理多个请求都返回结果的时候统一处理
7.遍历数组,遍历字典
8.字典转模型
rac的宏:
// 只要文本框文字改变,就会修改label的文字
RAC(self.accountLabel,text) = _textField.rac_textSignal;
一.通知
1.以前我们写注册完通知后,还需要写一个接受的方法,还需要在delloc removeObserver里面,但是使用RAC后,只需要一行代码就搞定.
知识拓展:这里说一下为啥通知需要delloc ,KVO会添加一个观察者,这个观察者一般是self,我们添加的观察者对self不是一个强引用,不然就造成循环引用了,虽然不是强引用,但是self销毁了,我们的观察依然会给self的响应方法发送消息,这就会造成崩溃,所以我们必须在self销毁的时候手动移除通知.
// 1.代替代理
// 需求:自定义redView,监听红色view中按钮点击
// 之前都是需要通过代理监听,给红色View添加一个代理属性,点击按钮的时候,通知代理做事情
// rac_signalForSelector:把调用某个对象的方法的信息转换成信号,就要调用这个方法,就会发送信号。
// 这里表示只要redV调用btnClick:,就会发出信号,订阅就好了。
[[redV rac_signalForSelector:@selector(btnClick:)] subscribeNext:^(id x) {
NSLog(@"点击红色按钮");
}];
// 2.KVO
// 把监听redV的center属性改变转换成信号,只要值改变就会发送信号
// observer:可以传入nil
[[redV rac_valuesAndChangesForKeyPath:@"center" options:NSKeyValueObservingOptionNew observer:nil] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 3.监听事件
// 把按钮点击事件转换为信号,点击按钮,就会发送信号
[[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
NSLog(@"按钮被点击了");
}];
// 4.代替通知
// 把监听到的通知转换信号
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
NSLog(@"键盘弹出");
}];
// 5.监听文本框的文字改变
[_textField.rac_textSignal subscribeNext:^(id x) {
NSLog(@"文字改变了%@",x);
}];
// 6.处理多个请求,都返回结果的时候,统一做处理.
RACSignal *request1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"发送请求1"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *request2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"发送请求2"];
[subscriber sendCompleted];
return nil;
}];
// 使用注意:几个信号,参数一的方法就几个参数,每个参数对应信号发出的数据。
[self rac_liftSelector:@selector(updateUIWithR1:r2:) withSignalsFromArray:@[request1,request2]];
}
// 更新UI
- (void)updateUIWithR1:(id)data r2:(id)data1
{
NSLog(@"更新UI%@ %@",data,data1);
}
7.遍历数组
//1.遍历数组
NSArray *arr = @[@"1",@"2",@"3"];
RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:arr];
// RACSequence RAC中的集合类,
//用于替代NSArray/NSDictionary 可以用它来遍历数组和字典 —— RAC常用
// RACSequence *sequence = arr.rac_sequence;
// //把集合转换成信号
// RACSignal *signal = sequence.signal;
// //订阅集合信号,内部会自动遍历所有元素发出来
// [signal subscribeNext:^(id _Nullable x) {
// NSLog(@"%@",x);
// }];
//将上面的代码简化 遍历数组
// 这里其实是三步
// 第一步: 把数组转换成集合RACSequence numbers.rac_sequence
// 第二步: 把集合RACSequence转换RACSignal信号类,numbers.rac_sequence.signal
// 第三步: 订阅信号,激活信号,会自动把集合中的所有值,遍历出来。
[arr.rac_sequence.signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
NSLog(@"%@",tuple[2]); //3
8.遍历字典
//2.遍历字典(遍历出来的键值对会包装成RACTuple(元组对象))
NSDictionary *dic = @{@"account":@"flower",@"age": @"18"};
//遍历字典
[dic.rac_sequence.signal subscribeNext:^(id _Nullable x) {
// NSString *key = x[0];
// NSString *value = x[1];
// NSLog(@"%@ %@",key,value);
//RACTupleUnpack: 用来解析元组
//宏里面的参数,传需要解析出来的变量名
// = 右边,放需要解析的元组
//等价于上面2行
RACTupleUnpack(NSString *key,NSString *value) = x;
NSLog(@"%@ %@",key,value);
}];
9.字典转模型
//3.字典转模型
//3.1 OC写法
NSDictionary *dict = [NSDictionary readLocalFileWithName:@"test"];
NSArray *dictArr = dict[@"data"];
NSMutableArray *items = [NSMutableArray array];
for (NSDictionary *dic in dictArr) {
RACBasicKnowledgeModel *item = [RACBasicKnowledgeModel modelWithDic:dic];
[items addObject:item];
}
//3.2RAC写法
NSMutableArray *lists = [NSMutableArray array];
[dictArr.rac_sequence.signal subscribeNext:^(id _Nullable x) {
RACBasicKnowledgeModel *model = [RACBasicKnowledgeModel modelWithDic:x];
[lists addObject:model];
}];
NSLog(@"lists: %@",lists);
//3.3 RAC高级写法
//会把集合中所有的元素都映射成一个新的对象
NSArray *lists1 = [[dictArr.rac_sequence map:^id _Nullable(NSDictionary * _Nullable value) {
//value 就是集合中的元素
//id 返回对象就是映射的值
return [RACBasicKnowledgeModel modelWithDic:value];
}] array];
NSLog(@"lists1: %@",lists1);