ReactiveCocoa vs RxSwift - 优点和缺点?

时间:2015-09-12 19:29:42

标签: swift reactive-programming rx-swift reactive-cocoa-3

所以现在使用swift,ReactiveCocoa人已经在版本3.0中重写了swift

此外,还有另一个名为RxSwift的项目。

我想知道人们是否可以添加关于两个框架的设计/ api /哲学的差异的信息(请在SO的精神中,坚持真实的事情,而不是关于哪个是#34的意见;最好的&#34)

[关于StackOverflow mods的注意事项:这个问题有确切的答案,答案是两个框架之间的差异。我认为这也是SO的主题。

要开始使用,我对阅读其自述文件的初步印象是:

  • 熟悉"真实"来自微软的C#Rx,RxSwift看起来更容易识别。
  • ReactiveCococa现在似乎进入了它自己的空间,引入了新的抽象,例如Signals vs SignalProducers和Lifting。一方面,这似乎澄清了一些情况(什么是Hot vs Cold信号),但另一方面,这似乎增加了框架的复杂性很多

1 个答案:

答案 0 :(得分:405)

这是一个非常好的问题。比较两个世界是非常困难的。 Rx是Reactive Extensions在其他语言(如C#,Java或JS)中的端口。

Reactive Cocoa受到功能反应式编程的启发,但在过去的几个月中,也被指向受Reactive Extensions启发。结果是一个与Rx共享一些东西的框架,但其名称起源于FRP。

首先要说的是,根据概念的Conal's definition,RAC和RxSwift都不是功能反应式编程实现。从这一点来看,一切都可以简化为每个框架如何处理副作用以及其他一些组件。

让我们谈谈社区和元技术的东西:

  • RAC是一个已有3年历史的项目,在完全放弃了Objective-C的正在进行的工作之后,出生于Objective-C,后来移植到Swift(带桥)。
  • RxSwift是一个几个月的项目,现在似乎在社区中有动力。对于RxSwift而言重要的一点是在ReactiveX组织下并且所有其他实现都以相同的方式工作,学习如何处理RxSwift将使Rx.Net,RxJava或RxJS成为一项简单的任务而只是语言语法的问题。我可以说这是基于哲学学习一次,适用于所有地方

现在是技术人员的时间。

制作/观察实体

RAC 3.0有两个主要实体,SignalSignalProducer,第一个实体发布事件,无论订阅者是否附加,第二个实体需要start实际拥有信号/产生的事件。这个设计是为了区分热和冷可观察的乏味概念而创建的,这对很多开发人员来说都是混乱的根源。这就是差异可以减少到如何管理副作用的原因。

在RxSwift中,SignalSignalProducer转换为Observable,这听起来可能令人困惑,但这两个实体在Rx世界中实际上是相同的。在RxSwift中设计Observable的设计必须考虑它们是热还是冷,它听起来可能是不必要的复杂性,但是一旦你理解了它们是如何工作的(再次热/冷/温暖就是这边)订阅/观察时的效果)可以驯服它们。

在这两个世界中,订阅的概念基本相同,RAC引入了一点点差异,并且在完成事件之前处置interruption时是Signal事件已经送走了。 回顾两者都有以下类型的事件:

  • Next,用于计算新收到的值
  • Error,计算错误并完成流,取消订阅所有观察员
  • Complete,将流标记为已完成取消订阅所有观察员

RAC另外还有interrupted,在正确完成或出错之前,Signal处理时会发送Signal

手动编写

在RAC中,SignalProducer / Observable是只读实体,无法从外部进行管理,RxSwift中的Signal也是如此。要将SignalProducer / pipe()转换为可写实体,您必须使用Subject函数返回手动控制的项目。在Rx空间中,这是一种名为Future的不同类型。

如果读/写概念听起来不熟悉,可以与Promise / Future进行类比。 Signal是一个只读占位符,例如SignalProducer / ObservablePromise,另一方面,pipe()可以手动完成,例如SubjectObservableType

调度程序

这个实体在两个世界中都是相似的,相同的概念,但RAC只是串行的,而RxSwift也是并发调度器。

组合物

组合是反应式编程的关键特性。组合流是两个框架的本质,在RxSwift中它们也被称为序列

RxSwift中的所有可观察实体都是Subject类型,因此我们使用相同的运算符组合ObservableSignal的实例,而不需要任何额外的关注。

在RAC空间中,SignalProducerlift是两个不同的实体,我们必须在SignalProducerSignal才能组合Action的实例生成的内容1}}。这两个实体有自己的运算符,所以当你需要混合东西时,你必须确保某个运算符可用,另一方面你忘记了热/冷可观察量。

关于这一部分,Colin Eberhardt总结得很好:

  

查看当前的API,信号操作主要集中在'next'事件,允许您在不同的线程上转换值,跳过,延迟,组合和观察。而信号生成器API主要关注信号生命周期事件(已完成,错误),其中包括flatMap,takeUntil和catch等操作。

附加

RAC还有PropertyAction的概念,前者是计算副作用的类型,主要与用户交互有关,后者在观察值时执行任务时很有意思价值已经改变。在RxSwift中,Observable再次转换为RxCocoa,这在Property很好地显示,是iOS和Mac的Rx原语的集成。 RAC的Variable可以在RxSwift中翻译为BehaviourSubject(或Property)。

了解Variable / start是我们必须将命令式世界与反应式编程的声明性本质联系起来的重要性,因此有时候这是处理时的一个基本组成部分。第三方库或iOS / Mac空间的核心功能。

结论

RAC和RxSwift是两个完全不同的野兽,前者在Cocoa领域有很长的历史和很多贡献者,后者相当年轻,但依赖于已被证明在Java等其他语言中有效的概念,JS或.NET。关于哪个更好的决定取决于偏好。 RAC指出热/冷可观察的分离是必要的,这是该框架的核心特征,RxSwift说它们的统一优于分离,再次它只是关于如何管理/执行副作用。

RAC 3.0似乎在分离热/冷可观察量的主要目标之上引入了一些意想不到的复杂性,例如中断的概念,在两个实体之间拆分运算符并引入一些命令行为,如{{1}}来开始生成信号。对于某些人来说,这些东西可能是一件好事,甚至是一个杀手级的功能,对于其他人来说,这些东西可能只是不必要甚至是危险的。另一件需要记住的事情是RAC试图尽可能地遵守Cocoa约定,所以如果你是一个经验丰富的Cocoa Dev,你应该感觉更舒服,而不是RxSwift。< / p> 另一方面,RxSwift存在所有缺点,如热/冷观察,以及Reactive Extensions的好处。从RxJS,RxJava或Rx.Net迁移到RxSwift是一件简单的事情,所有概念都是相同的,所以这使得查找材料非常有趣,可能是您现在面临的同样问题,已经被RxJava中的某个人解决了可以考虑平台重新应用。

必须挑选哪一个绝对是一个偏好的问题,从客观的角度来看,不可能分辨哪一个更好。唯一的方法是解雇Xcode并试用它们并选择一个感觉更舒适的工作。它们是类似概念的两种实现,试图实现相同的目标:简化软件开发。