ReactiveCocoa vs RxSwift - 長所と短所は? 質問する

ReactiveCocoa vs RxSwift - 長所と短所は? 質問する

Swiftでは、ReactiveCocoaの開発者がSwift向けにバージョン3.0を書き直しました。

また、 RxSwiftと呼ばれる別のプロジェクトも立ち上げられました。

2 つのフレームワークの設計/API/哲学の違いについて情報を追加していただけないでしょうか (SO の精神に則り、どちらが「ベスト」かという意見ではなく、真実にこだわってください)

まず、ReadMe を読んだ最初の印象は次のとおりです。

  • Microsoft の「本物の」C# Rx に精通している人にとっては、RxSwift の方がはるかに認識しやすいように見えます。
  • ReactiveCococa は、Signal vs SignalProducers や Lifting などの新しい抽象化を導入して、独自の領域に進出したようです。一方では、これはいくつかの状況 (Hot 信号と Cold 信号とは何か) を明確にしているように見えますが、他方では、フレームワークの複雑さが大幅に増加しているように見えます。

ベストアンサー1

これは非常に良い質問です。2 つの世界を比較するのは非常に困難です。Rx は、C#、Java、JS などの他の言語の Reactive Extensions を移植したものです。

Reactive Cocoa は、Functional Reactive Programmingからインスピレーションを得ましたが、ここ数か月は、Reactive Extensions からもインスピレーションを得たと指摘されています。その結果、Rx といくつかの共通点があるものの、FRP に由来する名前を持つフレームワークが生まれました。

The first thing to say is that neither RAC nor RxSwift are Functional Reactive Programming implementations, according to Conal's definition of the concept. From this point everything can be reduced to how each framework handles side effects and a few other components.

Let's talk about the community and meta-tech stuff:

  • RAC is a 3 years old project, born in Objective-C later ported to Swift (with bridges) for the 3.0 release, after completely dropping the ongoing work on Objective-C.
  • RxSwift is a few months old project and seems to have a momentum in the community right now. One thing that is important for RxSwift is that is under the ReactiveX organization and that all other implementations are working in the same way, learning how to deal with RxSwift will make working with Rx.Net, RxJava or RxJS a simple task and just a matter of language syntax. I could say that is based on the philosophy learn once, apply everywhere.

Now it's time for the tech stuff.

Producing/Observing Entities

RAC 3.0 has 2 main entities, Signal and SignalProducer, the first one publishes events regardless a subscriber is attached or not, the second one requires a start to actually having signals/events produced. This design has been created to separate the tedious concept of hot and cold observables, that has been source of confusion for a lot of developers. This is why the differences can be reduced to how they manage side effects.

In RxSwift, Signal and SignalProducer translates to Observable, it could sound confusing, but these 2 entities are actually the same thing in the Rx world. A design with Observables in RxSwift has to be created considering if they are hot or cold, it could sound as unnecessary complexity, but once you understood how they work (and again hot/cold/warm is just about the side effects while subscribing/observing) they can be tamed.

In both worlds, the concept of subscription is basically the same, there's one little difference that RAC introduced and is the interruption event when a Signal is disposed before the completion event has been sent. To recap both have the following kind of events:

  • Next, to compute the new received value
  • Error, to compute an error and complete the stream, unsubscribing all the observers
  • Complete, to mark the stream as completed unsubscribing all observers

RAC in addition has interrupted that is sent when a Signal is disposed before completing either correctly or with an error.

Manually Writing

RAC では、Signal/SignalProducerは読み取り専用エンティティであり、外部から管理することはできません。RxSwift でも同様です。 / を書き込み可能なエンティティにObservableするには、関数を使用して手動で制御される項目を返す必要があります。Rx 空間では、これは と呼ばれる別の型です。SignalSignalProducerpipe()Subject

Future読み取り/書き込みの概念に馴染みがない場合は、 /との類似性を考えPromiseてみましょう。 A は/Futureや のように読み取り専用のプレースホルダーですが、一方、 a はや のように手動で実現できます。SignalSignalProducerObservablePromisepipe()Subject

スケジューラ

このエンティティは両方の世界でほぼ同じで、概念も同じですが、RAC はシリアルのみであるのに対し、RxSwift は並行スケジューラも備えています。

構成

合成は、リアクティブ プログラミングの重要な機能です。ストリームの合成は両方のフレームワークの本質であり、RxSwift ではシーケンスとも呼ばれます。

RxSwift のすべての観測可能なエンティティは 型なのでObservableType、特別な配慮をすることなく、同じ演算子を使用して とSubjectのインスタンスを作成します。Observable

RAC 空間では、Signalと はSignalProducer2 つの異なるエンティティであり、のインスタンスで生成されるものを合成できるようにするにliftは を にする必要があります。 2 つのエンティティには独自の演算子があるため、物事を混合する必要がある場合は、特定の演算子が使用可能であることを確認する必要があります。その一方で、ホット/コールド観測可能オブジェクトについては忘れてしまいます。SignalProducerSignal

この部分については、コリン・エバーハートがうまくまとめています。

現在の API を見ると、シグナル操作は主に「次の」イベントに焦点を当てており、値の変換、スキップ、遅延、結合、および異なるスレッドでの監視が可能です。一方、シグナル プロデューサー API は主にシグナル ライフサイクル イベント (完了、エラー) に関係しており、then、flatMap、takeUntil、catch などの操作が含まれます。

余分な

ActionRAC にはとの概念もありますProperty。前者は主にユーザーインタラクションに関連する副作用を計算する型であり、後者は値を観察して値が変化したときにタスクを実行する場合に興味深いものです。RxSwift では はActionに再び変換されます。Observableこれは、iOS と Mac の両方の Rx プリミティブの統合である によく示されていますRxCocoa。RAC は、RxSwift では(または)Propertyに変換できます。VariableBehaviourSubject

Property/ は命令型の世界をリアクティブ プログラミングの宣言型の性質に橋渡しする方法であり、サードパーティのライブラリや iOS/Mac 空間のコア機能を扱うときに基本的なコンポーネントとなる場合があることを理解Variableすることが重要です。

結論

RAC と RxSwift は完全に異なる 2 つのものです。前者は Cocoa 分野で長い歴史があり、多くの貢献者がいます。後者は比較的新しいものですが、Java、JS、.NET などの他の言語で有効であることが証明されている概念に依存しています。どちらが優れているかは好みによります。RAC では、ホット/コールド オブザーバブルの分離が必要であり、それがフレームワークのコア機能であると述べています。RxSwift では、それらを統合する方が分離よりも優れていると述べています。繰り返しますが、これは副作用の管理/実行方法の問題です。

RAC 3.0 は、ホット/コールド観測可能オブジェクトを分離するという主な目標に加えて、割り込みの概念、2 つのエンティティ間の演算子の分割、start信号の生成を開始するなどの命令的な動作の導入など、予想外の複雑さを導入したようです。一部の人にとっては、これらは便利な機能、またはキラー機能になることもありますが、他の人にとっては不要、または危険ですらあります。覚えておくべきもう 1 つの点は、RAC は可能な限り Cocoa の規約に従おうとしていることです。そのため、経験豊富な Cocoa 開発者であれば、RxSwift よりも RAC の方が快適に作業できるはずです

一方、RxSwift は、ホット/コールド オブザーバブルなどのすべての欠点を抱えていますが、Reactive Extensions の良い点も持っています。RxJS、RxJava、または Rx.Net から RxSwift に移行するのは簡単で、すべての概念は同じであるため、資料を見つけるのは非常に興味深いものになります。おそらく、現在直面しているのと同じ問題が、RxJava の誰かによって解決されており、そのソリューションはプラットフォームを考慮して再適用できます。

どちらを選ぶかは好みの問題であり、客観的な観点からどちらが優れているかを判断することは不可能です。唯一の方法は、Xcode を起動して両方を試し、より使いやすい方を選択することです。これらは、ソフトウェア開発の簡素化という同じ目標を達成しようとする、同様の概念の 2 つの実装です。

おすすめ記事