ReactiveCocoa vs RxSwift - 优点和缺点?

Posted

技术标签:

【中文标题】ReactiveCocoa vs RxSwift - 优点和缺点?【英文标题】:ReactiveCocoa vs RxSwift - pros and cons? 【发布时间】:2015-12-09 03:48:42 【问题描述】:

所以现在有了 swift,ReactiveCocoa 的人们已经在 3.0 版中为 swift 重写了它

另外,还有一个名为 RxSwift 的项目启动了。

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

[*** 模组注意事项:这个问题确实有明确的答案,答案是两个框架之间的差异。我认为这对 SO 来说也很重要]

首先,我阅读他们的自述文件的最初印象是:

作为熟悉微软“真正的”C# Rx 的人,RxSwift 看起来更具辨识度。 ReactiveCococa 现在似乎已经进入了自己的领域,引入了新的抽象,例如 Signals vs SignalProducers 和 Lifting。一方面,这似乎澄清了某些情况(什么是热信号与冷信号),但另一方面,这似乎大大增加了框架的复杂性

【问题讨论】:

您的问题专门询问“意见”。你能改写吗?届时我将很乐意撤回我的近距离投票。 你可以去掉“添加他们的意见”,因为差异是事实,而不是意见。然后您可以喜欢或不喜欢 RAC/RxSwift 的某些功能,但差异非常明显。 哈哈哈,关于“模组注意事项”的好举动! 重命名问题:ReactiveCocoa 和 RxSwift 之间的区别。我认为一切都会成为“事实”,而这个问题是遗留问题。 即使解决方案以“这是一个非常好的问题”开头。 :| 【参考方案1】:

这是一个很好的问题。比较两个世界是非常困难的。 Rx 是响应式扩展在其他语言(如 C#、Java 或 JS)中的一个端口。

Reactive Cocoa 受到 Functional Reactive Programming 的启发,但在过去几个月中,也被指出也受到 Reactive Extensions 的启发。结果是一个框架,它与 Rx 共享一些东西,但名称起源于 FRP。

首先要说的是,根据Conal's definition 的概念,RAC 和 RxSwift 都不是 Functional Reactive Programming 实现。从这一点开始,一切都可以简化为每个框架如何处理副作用和其他一些组件。

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

RAC 是一个已有 3 年历史的项目,诞生于 Objective-C,后来在完全放弃了 Objective-C 正在进行的工作后移植到 Swift(带有桥接器)的 3.0 版本。 RxSwift 是一个几个月前的项目,现在似乎在社区中有一股势头。对 RxSwift 很重要的一件事是在 ReactiveX 组织下,并且所有其他实现都以相同的方式工作,学习如何处理 RxSwift 将使使用 Rx.Net、RxJava 或 RxJS 成为一项简单的任务,并且只需语言语法的问题。我可以说这是基于一次学习,无处不在的理念。

现在是技术方面的时候了。

生产/观察实体

RAC 3.0 有 2 个主要实体,SignalSignalProducer,第一个实体发布事件,无论是否附加订阅者,第二个实体需要 start 才能实际产生信号/事件。创建这种设计是为了将冷热可观察对象的繁琐概念分开,这一直是许多开发人员困惑的根源。这就是为什么差异可以减少到它们如何管理副作用

在 RxSwift 中,SignalSignalProducer 转换为 Observable,这听起来可能令人困惑,但这两个实体在 Rx 世界中实际上是同一个东西。必须在 RxSwift 中创建带有Observables 的设计,考虑它们是热的还是冷的,这听起来可能是不必要的复杂性,但是一旦你了解它们是如何工作的(同样热/冷/暖只是副作用,而订阅/观察)它们可以被驯服。

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

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

RAC 还具有 interrupted,当 Signal 在正确完成或出现错误之前被处置时发送。

手动书写

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

如果读/写概念听起来不熟悉,可以与Future/Promise 做一个很好的类比。 Future 是只读占位符,如Signal/SignalProducerObservable,另一方面,Promise 可以手动实现,如pipe()Subject

调度器

这个实体在两个世界中非常相似,相同的概念,但是 RAC 是仅串行的,相反 RxSwift 还具有并发调度程序。

作曲

组合是响应式编程的关键特征。组合流是这两个框架的本质,在 RxSwift 中它们也被称为 sequences

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

在 RAC 空间中,SignalSignalProducer 是 2 个不同的实体,我们必须在 SignalProducer 上使用 lift 才能组合使用 Signal 的实例生成的内容。这两个实体有自己的运算符,因此当您需要混合时,您必须确保某个运算符可用,另一方面您忘记了热/冷 observables。

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

查看当前的 API,信号操作主要集中在“下一个”事件上,允许您在不同线程上转换值、跳过、延迟、组合和观察。而信号生产者 API 主要关注信号生命周期事件(完成、错误),操作包括 then、flatMap、takeUntil 和 catch。

额外

RAC还有ActionProperty的概念,前者是计算副作用的类型,主要与用户交互有关,后者在值发生变化时观察值执行任务时很有趣.在 RxSwift 中,Action 再次转换为 Observable,这在 RxCocoa 中得到了很好的展示,这是一个适用于 ios 和 Mac 的 Rx 原语的集成。 RAC 的Property 可以在 RxSwift 中翻译成Variable(或BehaviourSubject)。

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

结论

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

RAC 3.0 似乎在分离热/冷 observables 的主要目标之上引入了一些意想不到的复杂性,例如中断的概念、在 2 个实体之间拆分运算符以及引入一些命令式行为(如start)开始产生信号。对于某些人来说,拥有这些东西可能是一件好事,甚至是杀手级功能,而对于另一些人来说,它们可能只是不必要的,甚至是危险的。另一件要记住的事情是,RAC 试图尽可能地跟上 Cocoa 的约定,所以如果你是一个有经验的 Cocoa 开发者,你应该觉得使用它比使用 RxSwift 更舒服。

另一方面,RxSwift 具有所有缺点,例如热/冷 observables,但也有反应式扩展的优点。从 RxJS、RxJava 或 Rx.Net 迁移到 RxSwift 是一件简单的事情,所有的概念都是相同的,所以这使得寻找材料变得非常有趣,也许你现在面临的同样的问题,已经被 RxJava 中的某个人解决了,并且解决方案可以根据平台重新应用。

选哪个绝对是个人喜好问题,从客观的角度无法判断哪个更好。唯一的方法是启动 Xcode 并尝试这两种方法,然后选择使用起来感觉更舒服的一种。它们是相似概念的 2 个实现,试图实现相同的目标:简化软件开发。

【讨论】:

这是一个很好的解释,@junior-b!然而,还值得一提的是,RAC 在流类型本身中编码类型信息(包括由于NoError 而没有错误):Signal<T, E: ErrorType>Observable<T>。这与热/冷分离一样,在编译时提供了更多的信息,而 RxSwift 所没有的信息量。 嗨@nachosoto,谢谢你的好话。我认为提议的添加在反应式编程的比较中不太适合。这绝对是 RAC 方面的一个很好的补充,但对我来说,RP 是关于简化数据流编程,重要的因素是:错误处理、异步计算、副作用管理和组合。从开发人员的角度来看,这似乎是一个不错的功能,这是为了澄清代码上的错误类型,并没有真正改善框架的错误处理方面,这当然是我的拙见。 值得一提的是,目前还缺乏关于 RAC 的像样的教程,但是有一些很棒的 RxSwift 示例项目对我来说是决定性的。 ReactiveCocoa 很好,直到他们引入了免费函数 SignalProducer,泛型带有错误。我学习了 RxSwift,并且在使用 RxKotlin、RxJS 时获得了相同的体验

以上是关于ReactiveCocoa vs RxSwift - 优点和缺点?的主要内容,如果未能解决你的问题,请参考以下文章

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

ReactiveCocoa / RxSwift 笔记一

可观察的选择器 - RxSwift

rxswift 绑定(onNext:VS 订阅(onNext:

RxSwift 调用 bind 立即触发 vs subscribe(onNext: )

iOS 函数式编程 - 实现响应式框架