免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3940 | 回复: 2
打印 上一主题 下一主题

[iOS] ReactiveCocoa - iOS开发的新框架 [复制链接]

论坛徽章:
39
白银圣斗士
日期:2015-11-24 10:40:40酉鸡
日期:2015-03-20 14:15:44寅虎
日期:2015-03-20 14:13:59午马
日期:2015-03-20 14:13:16白羊座
日期:2015-03-20 14:12:54金牛座
日期:2015-03-20 14:12:09双子座
日期:2015-03-20 14:11:57巨蟹座
日期:2015-03-20 14:11:44狮子座
日期:2015-03-20 14:11:29亥猪
日期:2015-03-20 14:16:24戌狗
日期:2015-03-20 14:16:40申猴
日期:2015-03-20 14:17:05
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-02-20 11:10 |只看该作者 |倒序浏览
什么是ReactiveCocoa
ReactiveCocoa(其简称为RAC)是由Github 开源的一个应用于iOS和OS X开发的新框架。RAC具有函数式编程和响应式编程的特性。它主要吸取了.Net的 Reactive Extensions的设计和实现。
ReactiveCocoa试图解决什么问题
经过一段时间的研究,我认为ReactiveCocoa试图解决以下3个问题:
  • 传统iOS开发过程中,状态以及状态之间依赖过多的问题
  • 传统MVC架构的问题:Controller比较复杂,可测试性差
  • 提供统一的消息传递机制
传统iOS开发过程中,状态以及状态之间依赖过多的问题
我们在开发iOS应用时,一个界面元素的状态很可能受多个其它界面元素或后台状态的影响。
例如,在用户帐户的登录界面,通常会有2个输入框(分别输入帐号和密码)和一个登录按钮。如果我们要加入一个限制条件:当用户输入完帐号和密码,并且登录的网络请求还未发出时,确定按钮才可以点击。通常情况下,我们需要监听这两个输入框的状态变化以及登录的网络请求状态,然后修改另一个控件的enabled状态。
传统的写法如下(该示例代码修改自ReactiveCocoa官网 ) :
  1. static void *ObservationContext = &ObservationContext;

  2. - (void)viewDidLoad {
  3.     [super viewDidLoad];

  4.     [LoginManager.sharedManager addObserver:self
  5.                                  forKeyPath:@"loggingIn"
  6.                                     options:NSKeyValueObservingOptionInitial
  7.                                     context:&ObservationContext];
  8.     [self.usernameTextField addTarget:self action:@selector(updateLogInButton)
  9.                      forControlEvents:UIControlEventEditingChanged];
  10.     [self.passwordTextField addTarget:self action:@selector(updateLogInButton)
  11.                      forControlEvents:UIControlEventEditingChanged];
  12. }

  13. - (void)updateLogInButton {
  14.     BOOL textFieldsNonEmpty = self.usernameTextField.text.length > 0 && self.passwordTextField.text.length > 0;
  15.     BOOL readyToLogIn = !LoginManager.sharedManager.isLoggingIn && !self.loggedIn;
  16.     self.logInButton.enabled = textFieldsNonEmpty && readyToLogIn;
  17. }

  18. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
  19.                         change:(NSDictionary *)change context:(void *)context {
  20.     if (context == ObservationContext) {
  21.         [self updateLogInButton];
  22.     } else {
  23.         [super observeValueForKeyPath:keyPath ofObject:object
  24.                                change:change context:context];
  25.     }
  26. }
复制代码
RAC通过引入信号(Signal)的概念,来代替传统iOS开发中对于控件状态变化检查的代理(delegate)模式或target-action模式。因为RAC的信号是可以组合(combine)的,所以可以轻松地构造出另一个新的信号出来,然后将按钮的enabled状态与新的信号绑定。如下所示:
  1. RAC(self.logInButton, enabled) = [RACSignal
  2.     combineLatest:@[
  3.         self.usernameTextField.rac_textSignal,
  4.         self.passwordTextField.rac_textSignal,
  5.         RACObserve(LoginManager.sharedManager, loggingIn),
  6.         RACObserve(self, loggedIn)
  7.     ] reduce:^(NSString *username, NSString *password, NSNumber *loggingIn, NSNumber *loggedIn) {
  8.         return @(username.length > 0 && password.length > 0 && !loggingIn.boolValue && !loggedIn.boolValue);
  9.     }];
复制代码
可以看到,在引入RAC之后,以前散落在action-target或KVO的回调函数中的判断逻辑被统一到了一起,从而使得登录按钮的enabled状态被更加清晰地表达了出来。
除了组合(combine)之外,RAC的信号还支持链式(chaining)和过滤(filter),以方便将信号进行进一步处理。
试图解决MVC框架的问题
对于传统的Model-View-Controller的框架,Controller很容易变得比较庞大和复杂。由于Controller承担了Model和View之间的桥梁作用,所以Controller常常与对应的View和Model的耦合度非常高,这同时也造成对其做单元测试非常不容易,对iOS工程的单元测试大多都只在一些工具类或与界面无关的逻辑类中进行。
RAC的信号机制很容易将某一个Model变量的变化与界面关联,所以非常容易应用Model-View-ViewModel 框架。通过引入ViewModel层,然后用RAC将ViewModel与View关联,View层的变化可以直接响应ViewModel层的变化,这使得Controller变得更加简单,由于View不再与Model绑定,也增加了View的可重用性。
因为引入了ViewModel层,所以单元测试可以在ViewModel层进行,iOS工程的可测试性也大大增强了。InfoQ也曾撰文介绍过MVVM:《MVVM启示录》
统一消息传递机制
iOS开发中有着各种消息传递机制,包括KVO、Notification、delegation、block以及target-action方式。各种消息传递机制使得开发者在做具体选择时感到困惑,例如在objc.io上就有专门撰文破船的翻译 ),介绍各种消息传递机制之间的差异性。
RAC将传统的UI控件事件进行了封装,使得以上各种消息传递机制都可以用RAC来完成。示例代码如下:
  1. // KVO
  2. [RACObserve(self, username) subscribeNext:^(id x) {
  3.     NSLog(@"成员变量 username 被修改成了:%@", x);
  4. }];

  5. // target-action
  6. self.button.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
  7.     NSLog(@"按钮被点击");
  8.     return [RACSignal empty];
  9. }];

  10. // Notification
  11. [[[NSNotificationCenter defaultCenter]
  12.     rac_addObserverForName:UIKeyboardDidChangeFrameNotification
  13.                     object:nil]
  14.     subscribeNext:^(id x) {
  15.         NSLog(@"键盘Frame改变");
  16.     }
  17. ];

  18. // Delegate
  19. [[self rac_signalForSelector:@selector(viewWillAppear:)] subscribeNext:^(id x) {
  20.     debugLog(@"viewWillAppear方法被调用 %@", x);
  21. }];
复制代码
RAC的RACSignal 类也提供了createSignal方法来让用户创建自定义的信号,如下代码创建了一个下载指定网站内容的信号。
  1. -(RACSignal *)urlResults {
  2.     return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
  3.         NSError *error;
  4.         NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.devtang.com"]
  5.                                                     encoding:NSUTF8StringEncoding
  6.                                                        error:&error];
  7.         NSLog(@"download");
  8.         if (!result) {
  9.             [subscriber sendError:error];
  10.         } else {
  11.             [subscriber sendNext:result];
  12.             [subscriber sendCompleted];
  13.         }
  14.         return [RACDisposable disposableWithBlock:^{
  15.             NSLog(@"clean up");
  16.         }];
  17.     }];

  18. }
复制代码
如何使用ReactiveCocoa
ReactiveCocoa可以在iOS和OS X的应用开发中使用,对于iOS开发者,可以将RAC源码下载编译后,使用编译好的libReactiveCocoa-iOS.a文件。
开发者也可以用CocoaPods来设置目标工程对ReactiveCocoa的依赖,只需要编辑Podfile文件,增加如下内容即可:
  1. pod 'ReactiveCocoa'
复制代码
ReactiveCocoa的特点
RAC在应用中大量使用了block,由于Objective-C语言的内存管理是基于引用计数 的,为了避免循环引用问题,在block中如果要引用self,需要使用@weakify(self)和@strongify(self)来避免强引用。另外,在使用时应该注意block的嵌套层数,不恰当的滥用多层嵌套block可能给程序的可维护性带来灾难。
RAC的编程方式和传统的MVC方式差异巨大,所以需要较长的学习时间。并且,业界内对于RAC并没有广泛应用,这造成可供参考的项目和教程比较欠缺。 另外,RAC项目本身也还在快速演进当中,1.x版本和2.x版本API改动了许多,3.0版本也正在快速开发中,对它的使用也需要考虑后期的升级维护问题。
作为一个iOS开发领域的新开源框架,ReactiveCocoa带来了函数式编程和响应式编程的思想,值得大家关注并且学习。
一些学习资源博客&教程代码书籍视频

论坛徽章:
0
2 [报告]
发表于 2014-05-26 12:02 |只看该作者
很不错的资源,顶一个

论坛徽章:
0
3 [报告]
发表于 2014-07-01 09:40 |只看该作者
顶一个@!!!!!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP