转载: iOS响应式编程:ReactiveCocoa vs RxSwift 选谁好

内容来自stack overflow的一个回答:ReactiveCocoa vs RxSwift – pros and cons?

要直接比较这两个有点难。Rx 是 Reactive Extensions 的一部分,其他语言像C#, Java 和 JS 也有。Reactive Cocoa 受 Functional Reactive Programming(FRP) 启发,但是在最近一段时间里,他们提到也受到Reactive Extensions的启发。最终结果就是一个从Rx借鉴了一些东西,但是有着源自FRP名声的一个框架。

第一点要说明的事是无论是RAC还是Rx都不是真正意义上的Functional Reactive Programming。按照 What is (functional) reactive programming 里的回答对于FRP概念的定义。有了这个认识,我们就可以从两个框架如何处理subscribing/observing时的副作用(side effect)和一些其他的组件上两个方面来比较。

我们来看看社区(community)和技术实现(extra-tech)。

RAC是一个已经有着3年历史的项目,从Objective-C时期开始,后来从3.0开始支持了swift(可以通过bridge在OC下使用),接着就完全停止了在Objective-C上的维护。RxSwift项目的时间短一些只有几个月(作者写的时间是15年),但是社区似乎充满了动力。关于RxSwift有一件重要的事是项目是按照 ReactiveX这个组织的规定下开发的,并且所有其他语言的Rx项目也是一样。如果学会了如何使用RxSwift,再去学习Rx.Net, RxJava 或者 RxJS就是小菜一碟,只是语言语法上的差异。这真的就是learn once, apply everywhere.

再来看看技术实现。

Producing/Observing Entities

RAC 3.0主要有两个实体,signal 和 SignalProducer。第一个发布事件无论是否有绑定订阅者,后者要有一个信号或者事件产生才会触发。这两个区别是为了区分冷信号和热信号,也使很多开发者困惑。这就是他们处理副作用的一大区别。

在RxSwift,signal 和 SignalProducer变成了 Observable,听起来有点困惑,但是这两个实体在Rx的世界里是同一个东西。在RxSwift里创建Observables不需要考虑是冷信号还是热信号,一旦你理解了他们的工作原理就很容易掌握。再次说明 冷/热(cold/hot/warm)信号就是当你subscribing/observing 产生的副作用。

对于订阅的概念两者基本是一样的。在RAC里有一点小的区别,RAC可以中断一个事件当信号被 disposed,即使在事件发送完成信号之前。总结一下两者都有的以下事件:

Next
处理新收到的值

Error
处理一个错误,结束整个流,对所有的观察者取消订阅

Complete
标记整个流已经完成,取消所有观察者的订阅

另外RAC会在收到一个disposed Signal后中断,即使没有收到complete或者error。

Manually Writing

在RAC中,Signal/SignalProducer都是只读的实体,他们不能从外部被改变,RxSwift中的Observable也是如此。如果要把Signal/SignalProducer改变成可以手动改写的实体,你只能通过调用pipe()函数返回一个可以改动的对象。在Rx中,这是一个不同的类型叫做Subject。

如果读/写这样的概念听起来不太明白,可以类比为未来/承诺(Future
/Promise)。未来只是一个只读的占位符(A Future is a read-only placeholder),就像Signal/SignalProducer和Observable。另外一方面,对于未来的承诺确可以手动自由的实现,就像pipe()和Subject。

Schedulers

这个部分两个框架都很类似,同样的概念。但是RAC是连续的,串行,Rx可以支持并发。

Composition

合成(Composition)是响应式编程的主要特点。合成成流都是两个框架的核心,在Rx中也称作sequences。

在Rx中所有observable的实体的类型都是ObservableType,所以我们可以轻松的用同一个操作符将Subject和Observable的实例组合(compose)起来。

在RAC中,Signal和SignalProducer是两种不同的对象。我们必须把SignalProducer转换成Signal后才能compose由Signal实例产生的信号。这两个对象拥有各自的操作符。所以当你需要混合使用它们时,你必须考虑到某种操作符是否是两者通用,这个时候你也不必关心冷/热的处理了。

关于这个部分, Colin Eberhardt 很好的总结了:

现在signal的API主要关注在处理‘next’上,让你可以改变值,skip, delay, combine并且在不同的线程里观察值。signal producer的API主要处理信号的生命周期事件(completed, error),和一些这样的操作:then, flatMap, takeUntil 和catch。

其他

在RAC中还有Action和 Property的概念。前者是一种处理副作用的类型,主要和用户交互相关。后者用于观察当执行了一个任务后值改变了的情况。在Rx中Action也会转变(translate)成一个 Observable类型。这在RxCocoa中有很好的体现,一个集成了Rx基本元素后用于iOS和Mac平台。RAC中的 Property可以对应于Rx中的 Variable或者 BehaviourSubject。

明白 Property/ Variable是我们连接必然世界和声明本质的响应式编程的的桥梁(bridge the imperative world to the declarative nature of Reactive Programming),所以当我们处理一些第三方库或者iOS/Mac中的核心功能(functionalities)时, Property/ Variable有时是基础。

结论

RAC和Rx可以说是两种完全不同的物种,前者在Cocoa里有着长的历史和大量的参与者,后者很年轻,但是依靠着已经在其他语言里像java、js或者C#被验证过的有效理念。关于选谁比较好还是要考虑到自己的情况。RAC认为把观察的对象区分为热/冷是非常有必要的,并且这也是他们框架的一个核心特点。Rx则认为把这个统一为一种对象更好。再次说明,这影响的只是怎么处理订阅后的副作用。

RAC 3.0 在为了区分观察时的热/冷状态还引入了意料之外的复杂度,比如中断的概念,区分两种对象间不同的操作,引入一些必要行为(imperative behaviour)比如start是开始产生信号。对于一些人来说,这些东西很好甚至是一个杀手级功能,对于另外一些人而言会觉得这个并没有必要甚至有些危险。另外需要记住的一点是RAC一直努力和Cocoa的惯例尽量保持一致,如果你是一个资深的Cocoa开发者,你在使用RAC应该会觉得比Rx更顺手。

Rx中所有的对象都是observables。好的一件事是,是Reactive Extensions中的一员。从RxJS, RxJava 或者 Rx.Net中迁移过来是一件非常简单的事,所有概念都是一样的。这也让解决问题时会很有趣,因为你现在面临的问题,可能在RxJava中已经有人写过解决方案,你可以直接拿过来按照当前平台实现就可以。

这两个应该选哪一个关键看使用习惯,从一个客观的角度来说无法分辨出谁更好。最好的方式是打开Xcode,都试着使用这两个框架,看看那个用起来比较顺手。他们都是相同编程理念的实现,尝试达到同一个目的:使开发软件变得简单(simplifying software development)。

相关链接:

函数式反应型编程(FRP) —— 实时互动应用开发的新思路
C语言里的side effect是什么意思?

iOS响应式编程:ReactiveCocoa vs RxSwift 选谁好的更多相关文章

  1. IOS响应式编程框架ReactiveCocoa(RAC)使用示例

    ReactiveCocoa是响应式编程(FRP)在iOS中的一个实现框架,它的开源地址为:https://github.com/ReactiveCocoa/ReactiveCocoa# :在网上看了几 ...

  2. IOS响应式编程框架ReactiveCocoa(RAC)使用示例-备

    ReactiveCocoa是响应式编程(FRP)在IOS中的一个实现框架,它的开源地址为:https://github.com/ReactiveCocoa/ReactiveCocoa# :在网上看了几 ...

  3. [iOS] 响应式编程开发-ReactiveCocoa(一)

    什么是响应式编程 响应式编程是一种面向数据流和变化传播的编程范式.这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播. 例如,在命令式编程环境中 ...

  4. [iOS] 响应式编程开发-ReactiveCocoa(二)

    RAC实现图片下载功能 在实现异步RAC下载图片的过程中,需要注意以下几点: • 通过 NSURLConnection 对象的 +(RACSignal *)rac_sendAsynchronousRe ...

  5. 使用ReactiveCocoa实现iOS平台响应式编程

    使用ReactiveCocoa实现iOS平台响应式编程 ReactiveCocoa和响应式编程 在说ReactiveCocoa之前,先要介绍一下FRP(Functional Reactive Prog ...

  6. [转]使用ReactiveCocoa实现iOS平台响应式编程

    原文:http://www.itiger.me/?p=38 使用ReactiveCocoa实现iOS平台响应式编程 ReactiveCocoa和响应式编程 在说ReactiveCocoa之前,先要介绍 ...

  7. ReactiveCocoa,最受欢迎的iOS函数响应式编程库(2.5版),没有之一!

    简介 项目主页: ReactiveCocoa 实例下载: https://github.com/ios122/ios122 简评: 最受欢迎,最有价值的iOS响应式编程库,没有之一!iOS MVVM模 ...

  8. iOS开发之OC篇-响应式编程Reactive Cocoa

    一.Reactive Cocoa 介绍 Reactive Cocoa 是 iOS 开发的一个 "重量级" 框架 高大上的概念:响应式编程 核心概念:信号 Signal 官方网站:h ...

  9. 函数响应式编程(FRP)框架--ReactiveCocoa

    由于工作原因,有段时间没更新博客了,甚是抱歉,只是,从今天開始我又活跃起来了,哈哈,于是决定每周更新一博.大家互相学习.交流. 今天呢.讨论一下关于ReactiveCocoa,这个採用函数响应式编程( ...

随机推荐

  1. zookeeper系列之十一—zookeeper会话超时

    1.会话概述 在Zookeeper中,客户端和服务端建立连接后,会话随之建立,生成一个全局唯一的会话ID(Session ID).服务器和客户端之间维持的是一个长连接,在SEESSION_TIMEOU ...

  2. RabbitMQ系列二(构建消息队列)

    从AMQP协议可以看出,MessageQueue.Exchange和Binding构成了AMQP协议的核心.下面我们就围绕这三个主要组件,从应用使用的角度全面的介绍如何利用RabbitMQ构建消息队列 ...

  3. 关于nodejs4.0 npm乱码以及离线全局安装时要注意的问题

    近期nodejs更新的到了4.~版本,融合了io.js,升级了v8引擎,对于之前的操作有些变化,在这里提醒大家注意: 1.npm在install和remove时发生乱码,并报出"runTop ...

  4. mysql DATE_ADD DATE_SUB

    一.DATE_ADD() 函数向日期添加指定的时间间隔. DATE_ADD(date,INTERVAL expr type)date 参数是合法的日期表达式.expr 参数是您希望添加的时间间隔. t ...

  5. BZOJ 1006 神奇的国度(弦图的染色数)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1006 题意:给定一个弦图,求最小染色数.就是用最小数目的颜色进行染色使得任意两个相邻的节 ...

  6. 2012 #3 Arcane Numbers

    Arcane Numbers 1 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Su ...

  7. VEP安装指南

    #下载依赖包 sudo apt-get install -y curl rsync tar make perl perl-base tabix #设置perl环境变量 export PERL_PATH ...

  8. 构建一个简单的Maven项目

    这里用Maven Archetype插件从空白开始创建简单的项目. 熟悉Maven 项目和Maven的核心概念. 关键词:构建生命周期(build lifecycle), Maven仓库(reposi ...

  9. Redis常用命令入门——列表类型(一级二级缓存技术)

    获取列表片段 redis > LRANGE KEY_NAME START END lrange命令比较常用,返回从start到stop的所有元素的列表,start和stop都是从0开始. (1) ...

  10. js之oop <一> 创建对象,构造器(class)

    js中除了基本类型,就是对象.可以说在js中处处皆对象. 由于js是弱语言,在编写的过程中很容易混淆 object 和 class 也就是对象和构造器. object(对象):一般对象都由var关键字 ...