Jetzt mit Swift haben die ReactiveCocoa- Leute es in Version 3.0 für Swift umgeschrieben
Außerdem wurde ein weiteres Projekt namens RxSwift gestartet .
Ich frage mich, ob die Leute Informationen über die Unterschiede in Design / API / Philosophie der beiden Frameworks hinzufügen könnten (bitte halten Sie sich im Sinne von SO an Dinge, die wahr sind, und nicht an Meinungen, die "am besten" sind).
[Hinweis für StackOverflow-Mods: Diese Frage hat endgültige Antworten, die Antwort sind die Unterschiede zwischen den beiden Frameworks. Ich denke, es ist auch sehr thematisch für SO]
Mein erster Eindruck beim Lesen der ReadMes ist:
- Als jemand, der mit dem "echten" C # Rx von Microsoft vertraut ist, sieht RxSwift viel besser erkennbar aus.
- ReactiveCococa scheint jetzt in seinen eigenen Raum gegangen zu sein und neue Abstraktionen wie Signale gegen Signalproduzenten und Heben eingeführt zu haben. Einerseits scheint dies einige Situationen zu klären (was ist ein Hot vs Cold-Signal), andererseits scheint dies die Komplexität des Frameworks um ein Vielfaches zu erhöhen
swift
reactive-programming
rx-swift
reactive-cocoa-3
Orion Edwards
quelle
quelle
Antworten:
Das ist eine sehr gute Frage. Der Vergleich der beiden Welten ist sehr schwierig. Rx ist eine Portierung von Reactive Extensions in anderen Sprachen wie C #, Java oder JS.
Reactive Cocoa wurde von Functional Reactive Programming inspiriert , wurde aber in den letzten Monaten auch von Reactive Extensions inspiriert . Das Ergebnis ist ein Framework, das einige Dinge mit Rx teilt, aber Namen mit Ursprung in FRP hat.
Das erste, was zu sagen ist, ist, dass weder RAC noch RxSwift gemäß Conals Definition des Konzepts Implementierungen der funktionalen reaktiven Programmierung sind . Ab diesem Punkt kann alles darauf reduziert werden, wie jedes Framework mit Nebenwirkungen und einigen anderen Komponenten umgeht.
Lassen Sie uns über die Community und Meta-Tech- Dinge sprechen :
Jetzt ist es Zeit für das technische Zeug.
Entitäten produzieren / beobachten
RAC 3.0 hat zwei Hauptentitäten,
Signal
undSignalProducer
die erste veröffentlicht Ereignisse, unabhängig davon, ob ein Teilnehmer angeschlossen ist oder nicht, die zweite erfordertstart
, dass tatsächlich Signale / Ereignisse erzeugt werden. Dieses Design wurde entwickelt, um das langwierige Konzept von heißen und kalten Observablen zu trennen, das für viele Entwickler Verwirrung stiftete. Aus diesem Grund können die Unterschiede auf die Art und Weise reduziert werden, wie sie mit Nebenwirkungen umgehen .In RxSwift
Signal
undSignalProducer
übersetztObservable
könnte es verwirrend klingen, aber diese beiden Entitäten sind in der Rx-Welt tatsächlich dasselbe. Ein Design mitObservable
s in RxSwift muss erstellt werden, wenn berücksichtigt wird, ob es heiß oder kalt ist. Es kann sich als unnötige Komplexität anhören. Wenn Sie jedoch erst einmal verstanden haben, wie sie funktionieren (und wieder ist heiß / kalt / warm, sind nur die Nebenwirkungen beim Abonnieren / Beobachten ) Sie können gezähmt werden.In beiden Welten ist das Abonnementkonzept grundsätzlich dasselbe. Es gibt einen kleinen Unterschied, den RAC eingeführt hat, und es ist das
interruption
Ereignis, wenn aSignal
entsorgt wird, bevor das Abschlussereignis gesendet wurde. Um beide zusammenzufassen, haben die folgenden Arten von Ereignissen:Next
, um den neu empfangenen Wert zu berechnenError
, um einen Fehler zu berechnen und den Stream zu vervollständigen, indem Sie alle Beobachter abmeldenComplete
, um den Stream als abgeschlossen zu markieren und alle Beobachter abzumeldenRAC hat zusätzlich,
interrupted
dass gesendet wird, wenn aSignal
entsorgt wird, bevor entweder korrekt oder mit einem Fehler abgeschlossen wird.Manuelles Schreiben
In RAC sind
Signal
/SignalProducer
schreibgeschützte Entitäten, sie können nicht von außen verwaltet werden, dasselbe gilt fürObservable
RxSwift. Um einSignal
/SignalProducer
in eine schreibbare Entität zu verwandeln , müssen Sie diepipe()
Funktion verwenden, um ein manuell gesteuertes Element zurückzugeben. Im Rx-Bereich ist dies ein anderer TypSubject
.Wenn das Lese- / Schreibkonzept ungewohnt klingt, kann eine schöne Analogie zu
Future
/Promise
hergestellt werden. AFuture
ist ein schreibgeschützter Platzhalter, wieSignal
/SignalProducer
undObservable
andererseitsPromise
kann a manuell erfüllt werden, wie fürpipe()
undSubject
.Scheduler
Diese Entität ist in beiden Welten ziemlich ähnlich, dieselben Konzepte, aber RAC ist nur seriell, stattdessen bietet RxSwift auch gleichzeitige Scheduler.
Komposition
Die Komposition ist das Hauptmerkmal der reaktiven Programmierung. Das Erstellen von Streams ist die Essenz beider Frameworks. In RxSwift werden sie auch als Sequenzen bezeichnet .
Alle beobachtbaren Entitäten in RxSwift sind vom Typ
ObservableType
, daher erstellen wir Instanzen vonSubject
undObservable
mit denselben Operatoren ohne zusätzliche Bedenken.Auf RAC-Raum,
Signal
undSignalProducer
sind 2 verschiedene Entitäten und wir müssenlift
aufSignalProducer
in der Lage sein, zu komponieren, was mit Instanzen von produziert wirdSignal
. Die beiden Entitäten haben ihre eigenen Operatoren. Wenn Sie also Dinge mischen müssen, müssen Sie sicherstellen, dass ein bestimmter Operator verfügbar ist. Auf der anderen Seite vergessen Sie die heißen / kalten Observablen.Über diesen Teil hat Colin Eberhardt es gut zusammengefasst:
Extra
RAC hat auch das Konzept von
Action
undProperty
das erstere ist ein Typ zur Berechnung von Nebenwirkungen, die sich hauptsächlich auf die Benutzerinteraktion beziehen. Das letztere ist interessant, wenn ein Wert beobachtet wird, um eine Aufgabe auszuführen, wenn sich der Wert geändert hat. In RxSwift dieAction
übersetzt wieder in einObservable
, ist dies schön in gezeigtRxCocoa
, eine Integration von Rx Primitiven sowohl für iOS und Mac. Die RACs können in RxSwiftProperty
inVariable
(oderBehaviourSubject
) übersetzt werden.Es ist wichtig zu verstehen, dass
Property
/Variable
die Art und Weise ist, wie wir die imperative Welt mit dem deklarativen Charakter der reaktiven Programmierung verbinden müssen. Daher ist dies manchmal eine grundlegende Komponente, wenn es um Bibliotheken von Drittanbietern oder Kernfunktionen des iOS / Mac-Bereichs geht.Fazit
RAC und RxSwift sind zwei völlig unterschiedliche Bestien. Ersteres hat eine lange Geschichte im Kakao-Raum und viele Mitwirkende. Letzteres ist noch recht jung, stützt sich jedoch auf Konzepte, die sich in anderen Sprachen wie Java, JS oder als wirksam erwiesen haben .NETZ. Die Entscheidung, welche besser ist, wird bevorzugt. RAC gibt an, dass die Trennung von heiß / kalt beobachtbar notwendig war und dass dies das Kernmerkmal des Frameworks ist. Laut RxSwift ist die Vereinheitlichung besser als die Trennung. Auch hier geht es nur darum, wie Nebenwirkungen verwaltet / durchgeführt werden.
RAC 3.0 scheint eine unerwartete Komplexität eingeführt zu haben, zusätzlich zu dem Hauptziel, heiße / kalte Observable zu trennen, wie das Konzept der Unterbrechung, die Aufteilung von Operatoren zwischen zwei Entitäten und die Einführung eines zwingenden Verhaltens
start
, um mit der Erzeugung von Signalen zu beginnen. Für manche Menschen können diese Dinge eine nette Sache oder sogar eine Killer-Funktion sein, für andere können sie einfach unnötig oder sogar gefährlich sein. Eine andere Sache, an die Sie sich erinnern sollten, ist, dass RAC versucht, so weit wie möglich mit den Kakao-Konventionen Schritt zu halten. Wenn Sie also ein erfahrener Kakao-Entwickler sind, sollten Sie sich wohler fühlen, damit zu arbeiten, als mit RxSwift.RxSwift hingegen lebt mit allen Nachteilen wie heißen / kalten Observablen, aber auch den guten Dingen von Reactive Extensions. Der Wechsel von RxJS, RxJava oder Rx.Net zu RxSwift ist eine einfache Sache. Alle Konzepte sind gleich. Daher ist es ziemlich interessant, Material zu finden. Vielleicht ist das gleiche Problem, mit dem Sie jetzt konfrontiert sind, von jemandem in RxJava und der Lösung gelöst worden kann unter Berücksichtigung der Plattform erneut angewendet werden.
Welches ausgewählt werden muss, ist definitiv eine Frage der Präferenz, aus objektiver Sicht ist es unmöglich zu sagen, welches besser ist. Die einzige Möglichkeit besteht darin, Xcode abzufeuern, beide auszuprobieren und den auszuwählen, mit dem Sie besser arbeiten können. Es handelt sich um zwei Implementierungen ähnlicher Konzepte, mit denen versucht wird, dasselbe Ziel zu erreichen: die Vereinfachung der Softwareentwicklung.
quelle
NoError
) in den Stream-Typen selbst codiert :Signal<T, E: ErrorType>
versusObservable<T>
. Dies sowie die Heiß / Kalt-Trennung bieten eine größere Menge an Informationen zur Kompilierungszeit, die Sie einfach nicht habenRxSwift
.