首页 文章

ReactiveCocoa vs RxSwift - 优点和缺点?

提问于
浏览
237

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

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

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

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

首先,我阅读ReadMe的最初印象是:

  • 作为熟悉微软的"real" C#Rx的人,RxSwift看起来更容易识别 .

  • ReactiveCococa似乎已经进入了热门与冷酷的信号,但另一方面,这似乎增加了框架的复杂性了很多

1 回答

  • 396

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

    Reactive Cocoa的灵感来自功能反应式编程,但在过去的几个月中,也被反应性扩展所启发 . 结果是一个与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有2个主要实体, SignalSignalProducer ,第一个发布事件而不管订户是否附加,第二个实体需要 start 来实际生成信号/事件 . 这个设计是为了区分热和冷可观察的乏味概念而创建的,这对很多开发人员来说都是混乱的根源 . 这就是 differences can be reduced to how they manage side effects 的原因 .

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

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

    • 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中它们也称为序列 .

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

    在RAC空间中, SignalSignalProducer 是两个不同的实体,我们必须在 SignalProducerlift 才能组合使用 Signal 实例生成的内容 . 这两个实体有自己的操作符,所以当你需要混合时,你必须确保某个操作符可用,另一方面你忘记了热/冷可观察量 .

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

    查看当前的API,信号操作主要集中在'next'事件上,允许您在不同的线程上转换值,跳过,延迟,组合和观察 . 而信号生成器API主要关注信号生命周期事件(已完成,错误),其中包括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或其他语言中有效的概念 . 净 . 关于哪个更好的决定取决于偏好 . RAC指出热/冷可观察的分离是必要的,这是该框架的核心特征,RxSwift说它们的统一优于分离,再次只是关于如何管理/执行副作用 .

    RAC 3.0似乎在分离热/冷可观测量的主要目标之上引入了一些意想不到的复杂性,例如中断的概念,在2个实体之间拆分运算符并引入一些命令行为,如 start 以开始产生信号 . 对于某些人来说,这些东西可能是一件好事,甚至是一个杀手级的功能,对于其他人来说,这些东西可能只是不必要甚至是危险的 . 另一件需要记住的事情是RAC试图尽可能地遵守Cocoa惯例,所以如果你是一个经验丰富的Cocoa Dev,你会觉得使用它比使用RxSwift更舒服 .

    另一方面,RxSwift存在所有缺点,如热/冷可观察性,以及Reactive Extensions的好处 . 从RxJS,RxJava或Rx.Net迁移到RxSwift是一件简单的事情,所有的概念都是相同的,所以这使得查找材料非常有趣,可能是您现在面临的同样问题,已经被RxJava中的某个人解决了可以考虑平台重新应用 .

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

相关问题