从0到1学习RAC

iOS ReactiveCocoa学习笔记(3):信号传递与数据

2019-06-13  本文已影响3人  一粒咸瓜子

本文知识点:RAC信号传递、RACSequence、RACTuple、利用RAC进行字典转模型。

1.RAC信号传递


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,可以使用它来快速遍历数组和字典。

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];
上一篇 下一篇

猜你喜欢

热点阅读