![](https://img.haomeiwen.com/i2974330/1b7268e5a31477bd.png)
本文知识点:RAC信号传递、RACSequence、RACTuple、利用RAC进行字典转模型。
1.RAC信号传递
- 代替代理:
rac_signalForSelector:
用于替代代理。 - 代替KVO:
rac_valuesAndChangesForKeyPath:
用于监听某个对象的属性改变。 - 监听事件:
rac_signalForControlEvents:
用于监听某个事件。 - 代替通知:
rac_addObserverForName:
用于监听某个通知。 - 监听文本框文字改变:
rac_textSignal:
只要文本框发出改变就会发出这个信号。 - 代替调度组:当界面有多次请求时,需要都获取到数据时,才能展示界面:
rac_liftSelector:withSignalsFromArray:Signals:
当传入的Signals
(信号数组),每一个signal
都至少sendNext
过一次,就会去触发第一个selector
参数的方法。- 使用注意:几个信号,参数一的方法就几个参数,每个参数对应信号发出的数据。
1.1 代码演示
A.常用控件RAC都有封装signal方法
Ex1:UIButton
//将UIControlEventTouchUpInside这个事件类型转换为信号
[[self.tapBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id _Nullable x) {
NSLog(@"按钮被点击啦");
}];
Ex2:手势
UITapGestureRecognizer *restureRecognizer = [UITapGestureRecognizer new];
[self addGestureRecognizer:restureRecognizer];
[[restureRecognizer rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
NSLog(@"手势");
}];
B. UIControl Send action & target
//view发出valueChanged事件
[[view rac_signalForControlEvents:UIControlEventValueChanged] subscribeNext:^(__kindof UIControl * _Nullable x) {
NSLog(@"%@",x);
}];
C. 代理 rac_signalForSelector
//当view内部的method方法被执行时
[[view rac_signalForSelector:@selector(method)] subscribeNext:^(RACTuple * _Nullable x) {
...
}];
D. 通知 rac_addObserverForName
UITextField *tf1 = [[UITextField alloc] initWithFrame:CGRectMake(30, 30, 200, 50)];
tf1.borderStyle = UITextBorderStyleLine;
[self.view addSubview:tf1];
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillChangeFrameNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
NSLog(@"%@", x);
}];
E. KVO rac_valuesAndChangesForKeyPath
_mArray = [NSMutableArray array];
[[self rac_valuesAndChangesForKeyPath:@"mArray" options:0 observer:self] subscribeNext:^(RACTwoTuple<id,NSDictionary *> * _Nullable x) {
NSLog(@"%@", x);
}];
[[self mutableArrayValueForKeyPath:@"mArray"] addObject:@1];
[[self mutableArrayValueForKeyPath:@"mArray"] addObject:@2];
Output:
2018-04-03 18:13:57.959540+0800 RACDemo[11295:583320] (
1
)
2018-04-03 18:13:57.959898+0800 RACDemo[11295:583320] (
1,
2
)
2.RAC数据对象
2.1 RACTuple
元组类,类似 NSArray,用来包装多个值。
解包元组:RACTupleUnpack(NSString *key, NSString *value) = x
会把元组的值 按顺序给参数里面的变量赋值。宏定义如下:
#define RACTupleUnpack_(...) \
metamacro_foreach(RACTupleUnpack_decl,, __VA_ARGS__) \
\
int RACTupleUnpack_state = 0; \
\
RACTupleUnpack_after: \
; \
metamacro_foreach(RACTupleUnpack_assign,, __VA_ARGS__) \
if (RACTupleUnpack_state != 0) RACTupleUnpack_state = 2; \
\
while (RACTupleUnpack_state != 2) \
if (RACTupleUnpack_state == 1) { \
goto RACTupleUnpack_after; \
} else \
for (; RACTupleUnpack_state != 1; RACTupleUnpack_state = 1) \
[RACTupleUnpackingTrampoline trampoline][ @[ metamacro_foreach(RACTupleUnpack_value,, __VA_ARGS__) ] ]
代码演示:
NSDictionary *dict = @{@"name":@"aab",@"age":@18};
[dict.rac_sequence.signal subscribeNext:^(id _Nullable x) {
// 解包元组,会把元组的值,按顺序给参数里面的变量赋值
RACTupleUnpack(NSString *key, NSString *value) = x;
NSLog(@"%@, %@", key, value);
}];
Output:
2018-04-04 14:25:35.309629+0800 RACDemo[28438:896531] name, aab
2018-04-04 14:25:35.310345+0800 RACDemo[28438:896531] age, 18
2.2 RACSequence
RAC 中的集合类,用来替代 NSArray、NSDictionary,可以使用它来快速遍历数组和字典。
- 第一步: 把数组转换成集合 RACSequence。
- 第二步: 把集合 RACSequence 转换 RACSignal 信号类。
- 第三步: 订阅信号,激活信号,会自动把集合中的所有值,遍历出来。
Array:
NSArray *array = @[@1, @2, @3];
[array.rac_sequence.signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
}];
Output:
2018-04-04 14:21:08.937986+0800 RACDemo[28313:891089] 1
2018-04-04 14:21:08.938413+0800 RACDemo[28313:891089] 2
2018-04-04 14:21:08.938843+0800 RACDemo[28313:891089] 3
Dictionary:
NSDictionary *dict = @{@"name":@"aab",@"age":@18};
[dict.rac_sequence.signal subscribeNext:^(id _Nullable x) {
// 解包元组,会把元组的值,按顺序给参数里面的变量赋值
RACTupleUnpack(NSString *key, NSString *value) = x;
NSLog(@"%@, %@", key, value);
}];
Output:
2018-04-04 14:25:35.309629+0800 RACDemo[28438:896531] name, aab
2018-04-04 14:25:35.310345+0800 RACDemo[28438:896531] age, 18
2.3 使用场景:字典转模型
2.3.1 基础版
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"students" withExtension:@"plist"];
NSArray *array = [NSArray arrayWithContentsOfURL:fileURL];
NSMutableArray <Person *> *mArray = [NSMutableArray array];
@weakify(self);
[array.rac_sequence.signal subscribeNext:^(id _Nullable x) {
Person *person = [Person modelWithDict: x];
[mArray addObject:person];
} completed:^{
@strongify(self);
self.dataArray = mArray.copy;
}];
//_dataArray = mArray.copy 写在外面无效。调用subscribeNext,并不会马上执行nextBlock,而是会等一会。
2.3.2 进阶版
方式:map 函数(遍历集合所有子元素并映射成一个新值)
toArray: 把集合转换成数组
底层实现:当信号被订阅,会遍历集合中的原始值,映射成新值,并且保存到新的数组里。
_dataArray = [[array.rac_sequence.signal map:^id _Nullable(id _Nullable value) {
return [Person modelWithDict:value];
}] toArray];
网友评论