NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

花瓣网李忠:ReactiveCocoa 是 Cocoa 的未来

  • 2014-07-02
  • 本文字数:3912 字

    阅读完需:约 13 分钟

ReactiveCocoa(其简称为 RAC)是由 Github 工程师们开发的一个应用于 iOS 和 OS X 开发的函数响应式编程新框架。ReactiveCocoa 为开发者带来了函数式编程和响应式编程的思想,被 Mattt Thompson 称为开启一个新 Objective-C 纪元。InfoQ 此次专访了花瓣网移动开发主管李忠,另外作为 ArchSummit 深圳 2014 大会《移动互联网,一浪高过一浪》专题的讲师,李忠将会分享 ReactiveCocoa 在花瓣客户端的实践。

InfoQ:使用 ReactiveCocoa 与直接使用 Cocoa 框架相比,性能上(事件的响应速度、回调速度)是否会有影响?

李忠:ReactiveCocoa 底层的实现是比较复杂的,在性能上确实会有一定的影响。一个简单的 [signal subscribeNext: ^(id x){}] 就会有造成很深的 callback stack(近 40 次的调用),相比纯 KVO 不到 10 次的调用,速度上慢了至少 1 个数量级。不过尽管如此,只要 subscribe 的次数不要过多,性能上还是可以接受的。

在事件响应上,RAC 比 KVO 慢了大概 5 倍,不过问题不大,在 iPhone5 上测了下,也就 1ms 多一点,绝大多数的使用场景都不会有问题。

在开发 Mac App 时,可以使用 Cocoa Bindings,但 iOS 却不支持,可能也是出于性能上的考虑。既然 RAC 的性能不如直接使用原生的高,还有必要用它么?我觉得还是有的,性能是我们选择框架的一个参考因素,但不是决定性的因素。开发者在足够了解 RAC 的情况下,RAC 可以提高开发效率并帮助开发者编写更易维护的代码,这两点就值得我们去研究、使用它。

InfoQ:使用 ReactiveCocoa 等于是放弃了 xib 或 StoryBoard,这样的话在开发界面的时候就需要通过代码去控制,这是否会降低开发效率?

李忠:iOS 开发 UI 界面主要有 3 种方式,手写 UI 代码、使用 xibs 来组织 UI、使用 StoryBoard 来组织 xibs,3 种方式各有优缺点。

  • 手写 UI 代码 (也是我目前采用的方式) 既然 xib 可以做的事情,代码都可以做到,而且 xib 做不了的事情,代码也可以做到,那为什么不直接用代码来写呢。很多人担心开发效率上会是一个很大的问题,我觉得或许会慢一点,但问题不大,尤其是结合了这样的 UIView Helper 之后。还有就是涉及到多人开发时,可以减少冲突,尤其是每个人负责各自的模块,基本不会出现这个情况。
  • 使用 xibs 来组织 UI 这也是不少开发者采用的模式,跟手写 UI 相比,最大的好处是直观且高效。Xcode4 的 xib 文件结构复杂且臃肿,很容易产生冲突,不过好在 Xcode5 对它进行了很大的改进,结构更加简单且易读。不过由于 UI 既可以在 xib 里调整,也可以在代码里调整,甚至是代码的不同地方进行调整,调试和维护都容易出现问题。
  • 使用 StoryBoard 好处很明显:非常直观。一共有多少个页面,每个页面是做什么的,页面之间如何关联都可以看得很清楚。问题也很大:多人协作,很容易出现冲突,要频繁地解决冲突还是挺影响效率的。当然如果只是一个人开发,那就没有问题了。

所以三种方式各有优劣,而使用 RAC 并不会强制你使用代码去构建 UI,依然可以用 xib/StoryBoard,它改变的是编程模式,对 UI 的影响其实不大。另外 RAC 还提供了一套 UIKit Extension,很多需要 Delegate/Target-Action 的 UI,可以直接使用 RAC 的方法,这也带来了很大的便利。

InfoQ:苹果每年都会有新的工具、新的 API 开放出来,比如 iOS 6 之后可以实现界面元素的相对布局等等,ReactiveCocoa 可以支持新的功能么?或者是能否基于 ReactiveCocoa 进行自定义扩展?

李忠:好比有一座房子,房子的主人每年都会对里面的家具做一些调整,如灯泡从白炽灯变成节能灯,洗衣机从半自动变成了全自动等等,也会新添置一些器材,如为了更爽地看世界杯,买了个投影仪,或为了更方便地打扫房间,买了个 iRobot 等等。

这座房子就好像 Cocoa,对家具的调整就好比新的 API,新的工具好比新的器材。而 RAC 并不会对现有的家具造成影响,它改变的只是墙体的结构,让它更稳固。

以 AutoLayout 为例,它可以实现界面的相对布局,比如 [NSLayoutConstraint constraintsWithVisualFormat:options:metrics:views:],RAC 并不会干扰这一过程。 但 AutoLayout 的一个特点:描述 View 之间的关系,而不是动态的去计算,是挺符合 RAC 的理念的,所以 RAC 也可以用来做这件事情。比如有两个 View:parentView 和 childView,假如当 parentView 的 bounds 改变时,childView 也要跟着改变,就可以这么做:

[RACObserve(parentView, layer.bounds) subscribeNext:^(id bounds){ childView.frame = CGRectInset(bounds, 5, 5); }];

RAC 的开发者觉得这样可行,于是就有了 ReactiveCocoaLayout,所以是否有必要基于 RAC 进行自定义扩展,需要看是否符合 RAC 的理念。

InfoQ:使用 ReactiveCocoa 带给你和你的团队最大的好处是什么? 最大的弊端是什么?

李忠:先来说说弊端吧,RAC 最大的问题在于它跟正常的编程模式太不一样了,就像第一次穿上溜冰鞋,很多人都会觉得不习惯,然后各种摔跤,因为不能再用“走路”的模式去实践了。所以学习成本是个很大的挑战。

其次 RAC 没有被大规模采纳,很少有人分享 Best Practices,或相关的文章,这时“贸然”地用到项目里,如果影响了开发效率怎么办?项目不能如期交付怎么办?其他团队成员不够熟悉怎么办?遇到问题找不到解决方案怎么办?这些都是要考虑的因素,所以如果要使用,必须对它有相当程度的了解,因此潜在的风险也是个大问题。

有一天同事 Dismory 说他已经用 RAC 开发了一个 App,并且感觉很不错,于是就决定在开发花瓣时用一下。因为我们是模块化开发,每个人会分到多个模块,所以也并不要求每个人都使用 RAC,可以按照自己最熟悉的方式去写,这也进一步降低了风险。

以前没有用 RAC 写过一个完整的项目,自然会遇到不少问题。最大的问题是:如何用 RAC 的理念去思考?因为不够熟悉,所以代码往往两不像,既不像 RAC,也不像 Cocoa。于是我就开始翻 issues 列表,看 RAC 作者写的 App 以及各类文章,慢慢地有点 get the point 了,写起来也顺手了。也会跟团队成员分享经验,讨论遇到的问题。开发效率的提升,代码复杂度降低这两点就是最大的好处。

InfoQ:今年的 WWDC 大会上苹果发布了 Swift 语言,未来苹果应该会大力支持 swift, 你认为 ReactiveCocoa 是否会基于 Swift 开发新版本?难度大吗?

李忠:由于 ObjectiveC 语言自身的限制,也影响到了 RAC 的一些特性,比如无法根据一个 Signal 得知它的 sendNext value 的类型,这是很不方便的,要么推断它的类型,要么去看接口说明,如果没有说明,那只能看源码。而 Swift 的 Generic 特性正好可以弥补这点。

除此之外,因为 Swift 没有 KVO,而 RAC 又是基于 KVO 实现的,所以如果要用 Swift 来重写,底层的改动还是挺大的。不过看起来他们正打算这么做。

这就会带来一些问题,如果项目是用 ObjectiveC 写的,那么就无法调用 Swift 的 Generic 方法,或者其他 Swift 具备的特性。另外目前 Swift 语言还没有到稳定版,接口和使用上也存在变动的可能。

我觉得他们应该是认同 Swift,且相信它会在将来成为主力开发语言,所以不如一次性地支持到位。如果还是使用 OC,那么可以用 RAC2,如果使用 Swift,那么就可以用 RAC3。

RAC3 借鉴了.NET 的 Rx 思想,通过 Observer / Observable / Enumerator / Enumerable 这 4 个基础类来实现 push/pull driven streams,架构上也更清晰了,使用 Swift 来实现这些特性应该也没什么问题。至于难度么,Just trust the github guys。

InfoQ:使用 ReactiveCocoa 需要时间成本,你认为值吗?是否建议新手直接使用 ReactiveCocoa 开发程序?

李忠:相比于其他的框架,ReactiveCocoa 的学习曲线更加陡峭,也就意味着需要花更多的时间。如果对 Cocoa 的设计模式、理念和常用 Framework 都已经很熟悉,也做过了几个成熟的 App,那么可以去更深入地了解下,比如如何用 RAC 的方式去解决 Cococa 编程遇到的问题,如何写出更 RAC 的代码等等。

有两种方法可以写出 bug-free 的代码。 1) 使用那些让 bug 更少的技术 2) 用自己熟悉的技术。如果对第一点吃不准,那么只使用第二点也没什么问题。

不建议新手直接使用 RAC 去开发程序,如果能做到这点,已经不是新手了,至少有不错的编程基础。如果只是自己做 Side Project 还行,涉及到多人合作,说服别人使用也是个难题,毕竟 RAC 不够 popular,且有着不可控的风险,而且将来别人来维护代码也会是个问题。

Cocoa 编程还有很多的挑战,这些不是学会了 RAC 就能解决的,对于大多数人我还是建议先看看,不用急着就在项目里使用,等 RAC3.0 出来后再考虑也不迟。

InfoQ:ReactiveCocoa 为 iOS 开发者带来了函数响应式编程, 统一了消息传递机制,你认为 ReactiveCocoa 还有哪些需要完善的地方?

李忠:ReactiveCocoa 需要完善的地方包括:

  • 性能 跟 pure KVO 相比,还是差了不少。比如光是 subscribNext 就慢了 1 个数量级,接收到新的 value 也慢了 5 倍左右。如果 signal 一多,subscription 也会跟着多起来,性能问题就会慢慢浮出水面。
  • signal 的 sendNext value 类型未知 感觉回到了脚本语言。只能根据 signal 名字去推断,或是看源码,不够 cool,且影响效率,还有出错的可能(比如正常应该发送 Number 的,忽然发送了 String),不过使用 Swift 应该能够解决这个问题。
  • 调试 目前的 callback stack 实在是深了点,最简单的 [signal subscribeNext^(id x){}] 就会有近 40 次的调用,项目跑起来,如果挂在了某个地方,往前追溯就得绕过那「厚厚」的一层 RAC 调用,真心累啊。
  • 命名 作为编程界的两大难题之一,RAC 在这块也有改进的空间,比如他们内部就会讨论 subscribe 这个名字是不是有问题,再想想 RACChannel 的命名等等,如果名字能够让使用者一看就明白,也算是降低了学习成本。
2014-07-02 04:144733
用户头像

发布了 219 篇内容, 共 135.0 次阅读, 收获喜欢 190 次。

关注

评论

发布
暂无评论
发现更多内容

第一时间快速了解 Kubernetes 1.25

云原生技术社区

容器 云原生 kubernetes入门 kubenetes Kubernetes, 云原生, eBPF

如何实现跨数百个K8s集群的管理

云原生技术社区

istio 服务网格 K8s 多集群管理 Istio流量管理

如何让工业制造拥有更强的“数字内核”?

天翼云开发者社区

使用 Canonical MAAS 部署 openEuler 测试

openEuler

centos 开源 操作系统 openEuler MaaS

Bytebase 1.3.1 - 2022.8.18

Bytebase

SQL优化 database SQL审批

2000字带您了解什么是 SD-WAN,它是如何工作的?

wljslmz

SD-WAN 网络技术 8月月更

翻译 | Kubernetes Operator 对数据库的重要性

RadonDB

Kubernetes operator RadonDB 数据库·

2022“易观之星”年度奖项启动征集,发现卓越数智力量

易观分析

报名 数智化 易观之星

“客户体验管理”这么热,究竟能给企业带来什么变化?

科技怪咖

实践基地+新工科实训 青软与西南大学展开多元校企合作

神奇视野

兆骑科创创新创业服务平台,云路演,人才引进平台

兆骑科创凤阁

工业智能化转型升级难?华为云这三招,加速商业变现

华为云开发者联盟

云计算 后端 华为云 工业智能化

天翼云为这场酷炫的元宇宙会议做了这件事

天翼云开发者社区

天翼云入选可信边缘计算推进计划与分布式云扬帆计划首批成员单位!

天翼云开发者社区

即刻报名|汽车制造行业如何玩转大数据分析?

Kyligence

数据分析 汽车制造

开源一夏 | MySQL 事务的隔离级别

六月的雨在InfoQ

开源 mysql事务 MySQL 数据库 8月月更

青软集团蝉联华为云「千万俱乐部奖」「最佳销售黑钻奖」两大奖项

神奇视野

"教练,我想打篮球!" —— 给做系统的同学们准备的 AI 学习系列小册

Zilliz

人工智能开源

天翼云TeleDB系列产品升级发布会开幕在即,精彩邀您共鉴

天翼云开发者社区

RT-Thread记录(十三、I/O 设备模型之PIN设备)

矜辰所致

RT-Thread 8月月更 I/O设备模型

关于Copy On Write Array List,你会安全使用么

华为云开发者联盟

List 开发

参与开源共建,你不可不知的贡献技巧

OpenHarmony开发者

OpenHarmony

阿里三面被面试官狂问Redis,简历上再也不敢写"精通"了

退休的汤姆

面试题 阿里 秋招 redis 底层原理

Golang 使用过程中遇到的小技巧(一)

皮特王

云上开发如何实现持续代码提交

华为云开发者联盟

云计算 后端 代码

企业搭建知识库的重要性,你了解多少?

Geek_da0866

重庆邮电大学新工科训练营 实践Java和大数据方向全真产业项目

神奇视野

翻译|是否应该在 Kubernetes 上运行数据库

RadonDB

MySQL Kubernetes RadonDB 数据库·

Mysql和Redis数据如何保持一致

京东科技开发者

数据 数据一致性 MySQL 数据库 数据库· redis 底层原理

DPDK技术原理与架构

C++后台开发

虚拟化 DDoS DPDK VPP NFV

金融机构求索数据价值,“数牍方案”提供可行解 数牍科技

Jessica@数牍

隐私计算 金融行业 数据隐私安全

花瓣网李忠:ReactiveCocoa是Cocoa的未来_语言 & 开发_小盖_InfoQ精选文章