zoukankan      html  css  js  c++  java
  • iOS ReactiveCocoa的使用

    一、ReactiveCocoa简介

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

    二、ReactiveCocoa基本用法

    (一)信号的创建、发送、接收

    上面提到RAC有着统一的消息传递机制,所以不难理解它的动作都离不开一个词:signal。
    1. //创建  
    2.     RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {  
    3.         //发送信号  
    4.         [subscriber sendNext:@"oh my god"];  
    5.         //回收资源  
    6.         return [RACDisposable disposableWithBlock:^{  
    7.             NSLog(@"信号发送完成");  
    8.         }];  
    9.     }];  
    10.     //订阅信号  
    11.     [signal subscribeNext:^(id x) {  
    12.         NSLog(@"singalContent:%@", x);  
    13.     }];  
    值得注意的是,手动创建一个signal一定要记得回收资源,不然程序会崩溃。
    打印顺序是先打印“oh my god”再打印“信号发送完成”。

    (二)RAC的ControlEvents

    1. [[self.textField rac_signalForControlEvents:UIControlEventEditingDidBegin] subscribeNext:^(id x) {  
    2.         NSLog(@"%@", x);  
    3.     }];  
    这个方法便简单的实现了监听操作,并且逻辑在其后的block中处理,同样的,还能对手势进行监听:
    1. UITapGestureRecognizer *tap = [UITapGestureRecognizer new];  
    2.     [[tap rac_gestureSignal] subscribeNext:^(id x) {  
    3.         NSLog(@"three:%@", x);  
    4.     }];  
    5.     [self.view addGestureRecognizer:tap];  

    (三)RAC的KVO

    1. [[self.textField rac_valuesAndChangesForKeyPath:@"text" options:NSKeyValueObservingOptionNew observer:self] subscribeNext:^(id x) {  
    2.         NSLog(@"%@", x);  
    3.     }];  

    (四)RAC的通知

    1. [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidShowNotification object:nil] subscribeNext:^(id x) {  
    2.         NSLog(@"键盘弹起");  
    3.     }];  

    (五)RAC的协议

    1. - (void)viewDidLoad {  
    2.     [super viewDidLoad];  
    3.     //代理  
    4.     self.textField.delegate = self;  
    5.     [[self rac_signalForSelector:@selector(textFieldDidBeginEditing:) fromProtocol:@protocol(UITextFieldDelegate)] subscribeNext:^(id x) {  
    6.         NSLog(@"此处打印点击信息:%@", x);  
    7.     }];  
    8. }  
    9. - (void)textFieldDidBeginEditing:(UITextField *)textField {  
    10.     NSLog(@"此刻开始编辑了");  
    11. }  
    从协议的写法可以看出,RAC的集合程度确实很高,如果需要写多个协议分类事件的触发,RAC有着极大的优越性。

    (六)RAC遍历数组和字典

    1. NSArray *arr = @[@"1", @"2", @"3", @"4", @"5"];  
    2.     [arr.rac_sequence.signal subscribeNext:^(id x) {  
    3.         NSLog(@"arr : %@", x);  
    4.     }];  
    5.     NSDictionary *dic = @{@"name":@"yangBo", @"age":@"19"};  
    6.     [dic.rac_sequence.signal subscribeNext:^(id x) {  
    7.         NSLog(@"dic : %@", x);  
    8.     }];  
    相对于枚举遍历,我还没有测试过他们的效率谁高,有兴趣的朋友可以用instruments简单测试下

    (七)RAC信号处理(map、filter、combine)

    (1)对信号不做处理

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

    (2)对信号进行过滤(filter)

    1. [[[self.textField rac_textSignal] filter:^BOOL(NSString* value) {  
    2.         if (value.length > 3) {  
    3.             return YES;  
    4.         }  
    5.         return NO;  
    6.     }] subscribeNext:^(id x) {  
    7.           
    8.         NSLog(@"filer:%@", x);  
    9.     }]; 
    1. <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">注意这个地方第一个block返回的是BOOL值,如果为NO,信号订阅者将得不到信号了(也就是第二个block不再打印值了)。</span>  

    (3)对信号进行映射(map)

    1. [[[self.textField rac_textSignal] map:^id(NSString* value) {  
    2.         if (value.length > 3) {  
    3.             return @"map now";  
    4.         }  
    5.         return value;  
    6.     }] subscribeNext:^(id x) {  
    7.         NSLog(@"map:%@", x);  
    8.     }];  
    映射也可以理解为转换,可以看到这里的第一个block返回的是id类型,所以如果你没有返回value,就视为信号转换,第二个block打印的值就是你return的值。

    (4)信号的联合(combine)

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

    (5)信号关联

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

    信号关联或联合是非常灵活的两个处理方式,在实际开发中往往能用很简单的代码实现匪夷所思的功能。
     

    三、总结

    RAC是一个强大的工具,这篇博客只是作为一个小小的总结,这还只是RAC的冰山一角,RAC的灵活而强大,是每一个iOS开发者值得深入研究的一门课题。
  • 相关阅读:
    Python的with语句(文件打开方式)
    python代码异常范围检查方法(非常实用)
    python一标准异常总结大全(非常全)
    python里pickle模块
    pyhon文件操作典型代码实现(非常经典!)
    codeblocks中cocos2dx项目添加新的.cpp和.h文件后编译运行的方法
    ubuntu安装cocos2dx
    学习资料整理
    Spring学习笔记--在SpEL中筛选集合
    Spring学习笔记--Spring表达式语言SpEL
  • 原文地址:https://www.cnblogs.com/FZP5/p/8205636.html
Copyright © 2011-2022 走看看