ReactiveCocoa 入门学习 (一)

引言

  现在由于需求的不断发展,MVC这个经典的框架由于Controller的任务越来越多,显得"臃肿"了,网上又推出了新的框架,比如MVVM,ReactiveCocoa, 今天就来学一下ReactiveCocoa框架,看看响应式编程的效果

  我是从ReactiveCocoa入门教程这篇文章上下载的Demo学习的,需要pod入ReactiveCocoa框架。

 

核心思想:

   RAC为应用中发生的不同事件流提供了一个标准接口。在ReactiveCocoa术语中这个叫做信号(signal),由RACSignal类表示。

 

示例使用:

 

  导入库后,就来到演示的登录界面的.m文件中,首先用框架自然导入其头文件。

1 #import "RWViewController.h"
2 #import "RWDummySignInService.h"
3 //导入ReactiveCocoa库的头文件
4 #import "ReactiveCocoa.h"

 

  RAC中扩展了UITextField和UITextView类,使用rac_textSignal,就可以监听用户输入的text啦。 还可以设置过滤条件,比如在输入少于4为的时候不给于显示。

 1     //监听textField
 2     [self.usernameTextField.rac_textSignal subscribeNext:^(id x) {
 3         NSLog(@"usernameTextField.text = %@", x);
 4     }];
 5     
 6     //密码框添加过滤条件:少于4位时不显示,过滤掉
 7   [[self.passwordTextField.rac_textSignal filter:^BOOL(id value) {
 8         //接受用户的输入密码
 9         NSString * text = value;
10         return text.length > 3;
11     }] subscribeNext:^(id x) {
12         NSLog(@"filterStr = %@", x);
13     }];

 

    原文说:ReactiveCocoa框架使用category来为很多基本UIKit控件添加signal。这样你就能给控件添加订阅了,text field的rac_textSignal就是这么来的。 
 1 /**
 2  *  过滤用户名
 3  */
 4 - (void)filterRACSignalTest{
 5 
 6     RACSignal *usernameSourceSignal = self.usernameTextField.rac_textSignal;
 7 
 8 //    //对信号添加过滤的条件
 9 //    RACSignal *filteredUsername = [usernameSourceSignal filter:^BOOL(id value) {
10 //        NSString *text = value;
11 //        return text.length > 3;
12 //    }];
13 //    
14 //    //监听过滤后的用户名打印
15 //    [filteredUsername subscribeNext:^(id x) {
16 //        NSLog(@"filteredUsername = %@", x);
17 //    }];
18     
19     //对信号添加过滤的条件
20     [[usernameSourceSignal filter:^BOOL(id value) {
21             NSString *text = value;
22             return text.length > 3;
23     }] subscribeNext:^(id x) {
24             NSLog(@"filteredUsername = %@", x);
25         }];
26     
27 }

 

 

  流程借用一下原文的图:

 

     使用subscriber来订阅需要监听对象的事件,RACSignal会发事件流给所对应的subscriber,目前总共有三种类型的事件:next、error、completed。一个signal在因error终止或者完成前,可以发送任意数量的next事件。

 

   添加map,返回text的长度,map操作通过block改变了事件的数据:

1     [[[usernameSourceSignal map:^id(NSString *text) {
2         return @(text.length);
3     }] filter:^BOOL(NSNumber *length) {
4         return [length integerValue] > 3;
5     }] subscribeNext:^(id x) {
6         NSLog(@"lenth = %@", x);
7     }];
8     

 

  可以使用map操作来把接收的对象转换成想要的类型 。

   

  

     细看UITextView (RACSignalSupport) 分类中rac_textSignal的构造方法,使用block来回调,果然是响应式的。

 1 - (RACSignal *)rac_textSignal {
 2     @weakify(self);
 3     RACSignal *signal = [[[[[RACSignal
 4         defer:^{
 5             @strongify(self);
 6             return [RACSignal return:RACTuplePack(self)];
 7         }]
 8         concat:[self.rac_delegateProxy signalForSelector:@selector(textViewDidChange:)]]
 9         reduceEach:^(UITextView *x) {
10             return x.text;
11         }]
12         takeUntil:self.rac_willDeallocSignal]
13         setNameWithFormat:@"%@ -rac_textSignal", self.rac_description];
14 
15     RACUseDelegateProxy(self);
16 
17     return signal;
18 }

 

  这是发送next事件部分~ 附上这一部分的Demo下载

 

 

参考文章:  http://www.cocoachina.com/ios/20150123/10994.html

posted on 2016-02-25 16:18  MichaelMao  阅读(986)  评论(0编辑  收藏  举报