当前位置: 首页 > news >正文

ReactiveCocoa学习

到我写这篇文章为止,ReactiveCocoa版本为5.0.1,搜了很多博客来了解ReactiveCocoa的基础用法,并不是很多,所以这篇文章算是自己对搜索资源的一个汇总,并加入一些自己在学习中遇到的问题和解决.

RAC 5.0 相比于 4.0 有了巨大的变化,不仅是受 swift 3.0 大升级的影响,RAC 对自身项目结构的也进行了大幅度的调整。这个调整就是将 RAC 拆分为四个库:ReactiveCocoa, ReactiveSwift, ReactiveObjC, ReactiveObjCBridge.

在项目里现在到底要引入哪些

如果你的项目是纯 OC 项目,你需要使用的是 ReactiveObjC 。这个库里面包含原来 RAC 2 的全部代码。 如果你只是纯 swift 项目,你继续使用ReactiveCocoa 。但是 RAC 依赖于 ReactiveSwift ,等于你引入了两个库。 如果你的项目是 swift 和 OC 混编,你需要同时引用 ReactiveCocoa 和 ReactiveObjCBridge 。但是 ReactiveObjCBridge 依赖于 ReactiveObjC ,所以你就等于引入了 4 个库。


ReactiveCocoa 试图解决什么问题

  1. 传统 iOS 开发过程中,状态以及状态之间依赖过多的问题
  2. 传统 MVC 架构的问题:Controller 比较复杂,可测试性差
  3. 提供统一的消息传递机制

传统 iOS 开发过程中,状态以及状态之间依赖过多的问题

我们在开发 iOS 应用时,一个界面元素的状态很可能受多个其它界面元素或后台状态的影响。 例如,在用户帐户的登录界面,通常会有 2 个输入框(分别输入帐号和密码)和一个登录按钮。如果我们要加入一个限制条件:当用户输入完帐号和密码,并且登录的网络请求还未发出时,确定按钮才可以点击。通常情况下,我们需要监听这两个输入框的状态变化以及登录的网络请求状态,然后修改另一个控件的enabled状态。 RAC 通过引入信号(Signal)的概念,来代替传统 iOS 开发中对于控件状态变化检查的代理(delegate)模式或 target-action 模式。因为 RAC 的信号是可以组合(combine)的,所以可以轻松地构造出另一个新的信号出来,然后将按钮的enabled状态与新的信号绑定。

RAC(self.loginBtn,enabled) = [RACSignal combineLatest:@[self.nameTF.rac_textSignal,
                                                        self.passwordTF.rac_textSignal
                                                        ]
                                                reduce:^(NSString *nameSignal,NSString *pwdSignal){
                                                            return @(nameSignal.length>=0 && pwdSignal.length>=0);
                                                        }];
复制代码

简单的解释一下代码: 这是将loginBtn的enable属性和帐号和密码两个输入框绑定,当两个输入框的文本都不为空的时候,loginBtn才可以点击. 注意一点,reduce后面的block并不会自动生成所有的返回值,需要根据自己在前面绑定的几个信号自己补全,然后直到这部分代码完全写完中间可能一直在报错,不要理他.从RAC的源码中可以看出来,前面绑定的信号不同后面的block返回值类型也是不同的.

统一消息传递机制

iOS 开发中有着各种消息传递机制,包括 KVO、Notification、delegation、block 以及 target-action 方式。各种消息传递机制使得开发者在做具体选择时感到困惑. 在引入 RAC 之后,以前散落在action-target或 KVO 的回调函数中的判断逻辑被统一到了一起.

// KVO
[RACObserve(self, username) subscribeNext:^(id x) {
    NSLog(@" 成员变量 username 被修改成了:%@", x);
}];
// target-action
self.button.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    NSLog(@" 按钮被点击 ");
    return [RACSignal empty];
}];
// Notification
[[[NSNotificationCenter defaultCenter] 
    rac_addObserverForName:UIKeyboardDidChangeFrameNotification         
                    object:nil] 
    subscribeNext:^(id x) {
        NSLog(@" 键盘 Frame 改变 ");
    }
];
// Delegate
[[self rac_signalForSelector:@selector(viewWillAppear:)] subscribeNext:^(id x) {
    debugLog(@"viewWillAppear 方法被调用 %@", x);
}];
复制代码

基础用法理解参考下面这篇文章吧,是翻译过来的,写得很棒,例子层层深入,慢慢读,就理解RAC的signal了.不过个人感觉想要深入了解,还是得自己多用. ReactiveCocoa入门教程——第一部

试图解决 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 的可重用性。

MVVM 的作用和问题 MVVM 在实际使用中,确实能够使得 Model 层和 View 层解耦,但是如果你需要实现 MVVM 中的双向绑定的话,那么通常就需要引入更多复杂的框架来实现了。 对此,MVVM 的作者 John Gossman 的 批评 应该是最为中肯的。John Gossman 对 MVVM 的批评主要有两点:

第一点:数据绑定使得 Bug 很难被调试。你看到界面异常了,有可能是你 View 的代码有 Bug,也可能是 Model 的代码有问题。数据绑定使得一个位置的 Bug 被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了。 第二点:对于过大的项目,数据绑定需要花费更多的内存。

附: 之前在上家公司用过一个MBMvc的框架来帮助分层,很好用,不过我看了一下github上已经很久没有更新了,怀疑是不是有什么问题停更了呢, 大家有兴趣的可以了解一下这个框架.


摘自: 唐巧 : ReactiveCocoa - iOS开发的新框架

转载于:https://juejin.im/post/5a4091dd6fb9a0450809e2e6

相关文章:

  • [POJ2411]Mondriaan's Dream
  • CentOS7防火墙
  • vue.js 初步学习资源
  • Atlassian发布JIRA项目组合管理解决方案
  • 图片后门恶意捆绑工具FackImageexploer
  • php扩展模块安装
  • Android Studio 3.0 Android 分析器 | 中文教学视频
  • GeoIP2 数据库更新地址
  • 个人常用iOS第三方库以及XCode插件介绍
  • 杭州数澜联合创始人 \u0026 CTO 江敏:大数据思维和大数据冶炼 —— 拒绝坐着金山吃馒头...
  • 重磅干货不容错过!2017云栖大会汇总资料,速来领取!
  • Linux—CentOS7,玩转samba服务,基于身份验证的共享
  • initial ram filesystem
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • 在Docker中运行tensorflow版的neural style
  • 2017 前端面试准备 - 收藏集 - 掘金
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • Map集合、散列表、红黑树介绍
  • Python_网络编程
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 写代码的正确姿势
  • ​Python 3 新特性:类型注解
  • #宝哥教你#查看jquery绑定的事件函数
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • (C语言)strcpy与strcpy详解,与模拟实现
  • (LeetCode 49)Anagrams
  • (rabbitmq的高级特性)消息可靠性
  • (定时器/计数器)中断系统(详解与使用)
  • (二)JAVA使用POI操作excel
  • (翻译)terry crowley: 写给程序员
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (原創) 未来三学期想要修的课 (日記)
  • .NET 4.0中的泛型协变和反变
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET Core中的去虚
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .Net Remoting常用部署结构
  • .NET Standard、.NET Framework 、.NET Core三者的关系与区别?
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .NET企业级应用架构设计系列之技术选型
  • ?php echo ?,?php echo Hello world!;?
  • @Autowired和@Resource的区别
  • []新浪博客如何插入代码(其他博客应该也可以)
  • []指针
  • [16/N]论得趣
  • [2023年]-hadoop面试真题(一)
  • [bzoj 3124][sdoi 2013 省选] 直径
  • [ERROR] 不再支持目标选项 5。请使用 7 或更高版本
  • [hdu2196]Computer树的直径
  • [JavaWeb]—前端篇
  • [Latex] \bibitem{} | .bbl 格式参考文献转换与获得