ReactiveCocoa的使用

124 阅读3分钟

ReactiveCocoa简称RAC,是函数响应式编程框架,因为它具有函数式编程和响应式编程的特性。

  • 由于该框架的编程思想,使得它具有相当魅惑人心的功能,它能实现传统设计模式和事件监听所能实现的功能,比如KVO、通知、block回调、action、协议等等,它的全面性并不是它最为优越的特色,RAC最值得炫耀的是它提供了统一的消息传递机制,这种机制使得它的代码更加的简洁,同一功能代码块更少,这正是符合了我们编程的思想:高聚合、低耦合,它非常适合MVVM设计模式的开发。
  • 不过它也并不能完全取代传统的编码方式,在多人开发和代码维护方面,RAC还是有着一些让人头痛的问题。

优点: 使用灵活方便、代码简洁、逻辑清晰
缺点: 维护成本较高、问题溯源困难
使用: RAC的统一消息传递机制,其所以动作都离不开信号(sigal)

  • 1). 信号的创建、发送、接收
// 创建  此时为冷信号,并不会被触发
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscribersubscriber) {  
    // 发送信号  
    [subscriber sendNext:@"oh my god"];  
    // 回收资源。注意:手动创建一个signal一定要记得回收资源,不然程序会崩溃
    return [RACDisposable disposableWithBlock:^{  
        NSLog(@"信号发送完成");  
    }];  
}];  
// 订阅信号后才会变为热信号,可以被触发
[signal subscribeNext:^(id x) {  
    NSLog(@"singalContent:%@", x);  
}];  
  • 2). RAC的ControlEvents 这个方法可以简单的实现监听操作,并且逻辑在其后的block中处理,而且也能添加手势并进行监听。
[[self.textField rac_signalForControlEvents:UIControlEventEditingDidBegin] subscribeNext:^(id x) {  
    NSLog(@"%@", x);  
}];  

UITapGestureRecognizer *tap = [UITapGestureRecognizer new];  
[[tap rac_gestureSignal] subscribeNext:^(id x) {  
    NSLog(@"three:%@", x);  
}];  
[self.view addGestureRecognizer:tap];  
  • 3). RAC的KVO
[[self.textField rac_valuesAndChangesForKeyPath:@"text" options:NSKeyValueObservingOptionNew observer:self] subscribeNext:^(id x) {  
    NSLog(@"%@", x);  
}];  
  • 4). RAC的通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidShowNotification object:nil] subscribeNext:^(id x) {  
    NSLog(@"键盘弹起");  
}];  
  • 5). RAC的协议
- (void)viewDidLoad {  
    [super viewDidLoad];  
    // 代理  
    self.textField.delegate = self;  
    [[self rac_signalForSelector:@selector(textFieldDidBeginEditing:) fromProtocol:@protocol(UITextFieldDelegate)] subscribeNext:^(id x) {  
        NSLog(@"打印点击信息:%@", x);  
    }];  
}  
- (void)textFieldDidBeginEditing:(UITextField *)textField {  
    NSLog(@"开始编辑了");  
}  
  • 6). RAC遍历数组和字典

相当于枚举遍历,但是效率相比更高

NSArray *arr = @[@"1", @"2", @"3", @"4", @"5"];  
[arr.rac_sequence.signal subscribeNext:^(id x) {  
    NSLog(@"arr : %@", x);  
}];  
NSDictionary *dic = @{@"name":@"yangBo", @"age":@"19"};  
[dic.rac_sequence.signal subscribeNext:^(id x) {  
    NSLog(@"dic : %@", x);  
}];  
  • 7). RAC信号处理(map、filter、combine)

① 对信号不做处理

[[self.textField rac_textSignal] subscribeNext:^(id x) {  
    NSLog(@"doNothing:%@", x);  
}];  

② 对信号进行过滤(filter) 可以对信号进行条件判断是否处理。

[[[self.textField rac_textSignal] filter:^BOOL(NSString* value) {
    if (value.length 3) {
        return YES;
    }
    return NO;
}] subscribeNext:^(id x) {
    NSLog(@"filter:%@", x);
}];

③ 对信号进行映射(map) 映射也可以理解为转换,第一个block返回的是id类型,如果返回"map now",就相当于信号转换,第二个block打印的值就是你return的值"map now"

[[[self.textField rac_textSignal] map:^id(NSString* value) {
    if (value.length 3) {
        return @"map now";
    }
    return value;
}] subscribeNext:^(id x) {
    NSLog(@"map:%@", x);
}];

④ 信号的联合(combine)

// 创建需要联合的信号
RACSignal *firstCombineSignal = [self.textField rac_textSignal];
RACSignal *secondeCombineSignal = [tap rac_gestureSignal];
// 信号联合处理返回self.label的背景色
RAC(self.label, backgroundColor) = [RACSignal combineLatest:@[firstCombineSignal, secondeCombineSignal] reduce:^id(NSString *text, UITapGestureRecognizer * tap){
    // 这里进行信号逻辑判断和处理
    if (text.length == 3 && tap.state == UIGestureRecognizerStateEnded) {
        return [UIColor redColor];
    }
    return [UIColor cyanColor];
}];

⑤ 信号关联

RAC(self.label, text) = [self.textField rac_textSignal];