1. ホーム
  2. スイフト

[解決済み】ReactiveCocoaとRxSwiftの比較 - 長所と短所?

2022-04-21 20:06:22

質問

では、今度はswiftで リアクティブココア は、バージョン3.0でswift用に書き直されました。

また、別のプロジェクトとして RxSwift .

この2つのフレームワークのデザイン/api/哲学の違いについて、情報を追加してもらえないでしょうか(SOの精神に則り、どちらが"best"という意見ではなく、真実であることにこだわってください)。

[StackOverflowのmodsに注意。この質問には明確な答えがあり、その答えは2つのフレームワークの違いです。また、SOのトピックに非常に近いと思います]。

まず始めに、両社のReadMeを読んでの第一印象は。

  • マイクロソフトのC# Rxに慣れている者としては、RxSwiftの方がずっと分かりやすく見える。
  • ReactiveCococaは、Signals vs SignalProducersやLiftingなどの新しい抽象概念を導入し、独自の領域に踏み込んだようです。一方では、これはいくつかの状況(ホットシグナルとコールドシグナルとは何か)を明確にしているようだが、他方ではフレームワークの複雑さを大きくしているようだ。

どのように解決するのか?

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

Reactive Cocoaは、以下のものにインスパイアされました。 機能的リアクティブ・プログラミング という指摘もありましたが、ここ数ヶ月は リアクティブ・エクステンションに触発された もあります。その結果、Rxといくつかのものを共有しながらも、FRPに由来する名前を持つフレームワークが生まれました。

まず最初に言っておきたいのは、RACもRxSwiftも 機能的リアクティブ・プログラミング によると コナールの定義 という概念があります。ここから先は、各フレームワークが副作用をどのように扱うか、そして他のいくつかの要素に還元されます。

では、コミュニティと メタ技術 のものです。

  • RACは3年前のプロジェクトで、Objective-Cで生まれ、その後Objective-Cで進行中の作業を完全に中止した後、3.0のリリースに向けてSwiftに(ブリッジを使って)移植されたものです。
  • RxSwiftは数ヶ月前のプロジェクトで、今コミュニティで勢いがあるようです。RxSwiftにとって重要なことのひとつは、RxSwiftが、このプロジェクトで使用されている リアクティブエックス RxSwiftの扱い方を学ぶことで、Rx.Net、RxJava、RxJSを扱うのが簡単になり、言語のシンタックスの問題になるだけです。それは、哲学に基づいていると言えます 一度学べば、どこでも応用できる .

さて、いよいよ技術的な話です。

プロデュース/オブザベーション・エンティティ

RAC 3.0には、主に2つのエンティティがあります。 SignalSignalProducer 前者はサブスクライバーが接続されているかどうかに関係なくイベントをパブリッシュし、後者は start を、実際にシグナルやイベントを発生させることができます。このデザインは、多くの開発者を混乱させる原因となっている、ホットとコールドのオブザーバブルの面倒な概念を分離するために作成されました。このため 違いは、副作用の管理方法に集約されます。 .

RxSwiftでは。 SignalSignalProducer は、次のように変換されます。 Observable しかし、この2つはRxの世界では同じものなのです。デザインに Observable それは不必要に複雑に聞こえるかもしれませんが、いったんそれらがどのように動作するかを理解すれば(そしてまた、hot/cold/warmは購読/観察中の副作用についてだけです)、それらは飼いならすことができます。

どちらの世界でも、サブスクリプションのコンセプトは基本的に同じですが、RACが導入した1つの小さな違いがあり、それは interruption イベントが発生した場合 Signal は完了イベントが送信される前に破棄されます。 まとめると、両者は以下のような種類のイベントを持っています。

  • Next は、新しい受信値を計算するために
  • Error エラーを計算し、ストリームを完了させ、すべてのオブザーバを退会させる。
  • Complete ストリームを完了とマークし、すべてのオブザーバを退会させる。

RACは、さらに interrupted が送信されたときに送信されます。 Signal が正しく終了するか、あるいはエラーで終了する前に廃棄される。

手動で書き込む

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

読み書きの概念がよくわからないという方は、以下の例えをご覧ください。 Future / Promise ができる。A Future は読み取り専用のプレースホルダーで、例えば Signal / SignalProducerObservable を、一方では Promise のように、手動で満たすことができます。 pipe()Subject .

スケジューラ

このエンティティは、両方の世界で非常によく似ており、コンセプトも同じですが、RACはシリアルのみであるのに対し、RxSwiftは並列スケジューラも備えているのが特徴です。

構成

コンポジションは、Reactive Programmingの重要な機能です。ストリームを構成することは、両方のフレームワークの本質であり、RxSwiftでは、ストリームは、次のようにも呼ばれます。 シーケンス .

RxSwiftの観測可能なエンティティはすべて、タイプ ObservableType のインスタンスを合成しています。 SubjectObservable を同じ演算子で使用することで、余計な心配をせずに済みます。

RACスペースについて。 SignalSignalProducer は2つの異なるエンティティであり lift オン SignalProducer のインスタンスで生成されたものを合成することができるようになります。 Signal . この2つのエンティティはそれぞれ演算子を持っているので、混合する必要があるときは、特定の演算子が利用可能であることを確認する必要があり、一方では、hot/cold observablesのことを忘れてしまいます。

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

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

おまけ

RACには、以下のようなコンセプトもあります。 ActionProperty 前者は主にユーザーとの対話に関連する副作用を計算する型であり、後者は値が変化したときにタスクを実行するために値を観察するときに興味深い型である。RxSwiftでは Action に変換されます。 Observable でうまく表現されています。 RxCocoa iOSとMacの両方に対応したRxプリミティブの統合です。RACの Property に変換することができます。 Variable (または BehaviourSubject をRxSwiftで使用することができます。

ここで重要なのは Property / Variable は、命令型の世界とReactive Programmingの宣言型の性質の橋渡しをする方法であり、サードパーティのライブラリやiOS/Mac空間の中核機能を扱う際の基本要素になることがあります。

まとめ

RACとRxSwiftは全く別のもので、前者はCocoaの分野で長い歴史を持ち、多くの貢献者がいます。後者はかなり若いですが、Java、JS、.NETなどの他の言語で有効であることが証明されている概念に依存しています。どちらが優れているかは、好みで判断してください。RAC は hot/cold observable の分離が必要であり、それがフレームワークの中核機能であると述べ、RxSwift は分離よりも統合の方が良いと述べ、やはり副作用の管理/実行方法についてのみ述べています。

RAC 3.0では、ホット/コールド観測値の分離という大きな目標の上に、中断の概念、2つのエンティティ間の演算子の分割、そして、以下のような命令的な動作の導入など、予想外の複雑さが加わったように思えます。 start を使用して、信号の生成を開始します。これらの機能は、ある人にとってはありがたいものであったり、キラー機能であったりしますが、ある人にとっては不要であったり、危険であったりすることもあります。もうひとつ覚えておいてほしいのは、RACはCocoaの規約に可能な限り追従しようとしていることです。 すべき RxSwiftよりも快適に作業することができます。

一方、RxSwiftは、Reactive Extensionsのホット/コールドオブザーバブルのようなマイナス面だけでなく、良い面も持ち合わせています。RxJS、RxJava、Rx.NetからRxSwiftへの移行は簡単で、すべてのコンセプトが同じなので、材料を見つけるのがとても面白くなります。おそらく今あなたが直面している同じ問題は、RxJavaで誰かが解決していて、プラットフォームを考慮した解決策が再適用されるでしょう。

どれを選ぶかは好みの問題で、客観的に見ればどちらが優れているかはわかりません。Xcodeを起動し、両方を試してみて、より快適に作業できる方を選ぶしかないでしょう。この2つは同じようなコンセプトの実装で、ソフトウェア開発の簡略化という同じ目標を達成しようとしています。