Alors maintenant, avec Swift, les ReactiveCocoa l'ont réécrit dans la version 3.0 pour Swift
En outre, il y a eu un autre projet appelé - RxSwift .
Je me demande si les gens pourraient ajouter des informations sur les différences de conception/interface/philosophie des deux cadres (s'il vous plaît, dans l'esprit de SO, tenez-vous-en aux choses qui sont vraies plutôt qu'aux opinions sur ce qui est "le meilleur")
[Note pour les mods StackOverflow: Cette question a des réponses définitives, la réponse est la différence entre les deux frameworks. Je pense que c'est aussi très sur le sujet pour SO]
Pour commencer, mon impression initiale à la lecture de leur fichier ReadMe est la suivante:
C'est une très bonne question. Comparer les deux mondes est très difficile. Rx est un portage de ce que sont les extensions réactives dans d'autres langages tels que C #, Java ou JS.
Le cacao réactif a été inspiré par Programmation réactive fonctionnelle, mais au cours des derniers mois, il a également été désigné comme inspiré par les extensions réactives. Le résultat est un cadre qui partage certaines choses avec Rx, mais qui a des noms d'origine dans FRP.
La première chose à dire est que ni RAC ni RxSwift ne sont des implémentations de Programmation Réactive Fonctionnelle, conformément à définition de Conal du concept. À partir de ce moment, tout peut être réduit à la manière dont chaque framework gère les effets secondaires et quelques autres composants.
Parlons de la communauté et meta-tech stuff:
Il est maintenant temps de passer aux choses techniques.
Le RAC 3.0 a 2 entités principales, Signal
et SignalProducer
, la première publie des événements, qu'un abonné soit connecté ou non, la seconde nécessite un start
pour que les signaux/événements soient réellement produits. Cette conception a été créée pour séparer le concept fastidieux d’observables chauds et froids, source de confusion pour de nombreux développeurs. C'est pourquoi les différences peuvent être réduites à la manière dont elles gèrent les effets secondaires .
Dans RxSwift, Signal
et SignalProducer
se traduisent par Observable
, cela peut sembler déroutant, mais ces 2 entités sont en réalité la même chose dans le monde des Rx. Un design avec Observable
s dans RxSwift doit être créé, car chaud ou froid, cela peut sembler une complexité inutile, mais une fois que vous avez compris comment ils fonctionnent (et encore chaud/froid/chaud, ce sont les effets secondaires en souscrivant/observant), ils peuvent être apprivoisés.
Dans les deux mondes, le concept d'abonnement est fondamentalement le même, il y a une petite différence que RAC a introduite et est l'événement interruption
lorsqu'un événement Signal
est supprimé avant l'envoi de l'événement d'achèvement. Pour récapituler, les deux types d'événements sont les suivants:
Next
, pour calculer la nouvelle valeur reçueError
, pour calculer une erreur et compléter le flux, en désabonnant tous les observateursComplete
, pour marquer le flux comme terminé, désinscription de tous les observateursDe plus, le RAC a interrupted
envoyé lorsqu’un Signal
est supprimé avant d’être terminé correctement ou avec une erreur.
Dans RAC, Signal
/SignalProducer
sont des entités en lecture seule, elles ne peuvent pas être gérées de l'extérieur. Même chose pour Observable
dans RxSwift. Pour transformer une Signal
/SignalProducer
en une entité en écriture, vous devez utiliser la fonction pipe()
pour renvoyer un élément contrôlé manuellement. Sur l’espace Rx, il s’agit d’un type différent appelé Subject
.
Si le concept de lecture/écriture ne semble pas familier, une analogie de Nice avec Future
/Promise
peut être réalisée. Un Future
est un espace réservé en lecture seule, comme Signal
/SignalProducer
et Observable
, par contre, un Promise
peut être rempli manuellement, comme pour pipe()
et Subject
.
Cette entité est à peu près similaire dans les deux mondes, les mêmes concepts, mais RAC est en série uniquement. RxSwift présente également des programmateurs simultanés.
La composition est la principale caractéristique de la programmation réactive. La composition des flux est l’essence des deux frameworks. Dans RxSwift, ils sont également appelés séquences.
Toutes les entités observables dans RxSwift sont de type ObservableType
, nous composons donc des instances de Subject
et Observable
avec les mêmes opérateurs, sans souci supplémentaire.
Sur l'espace RAC, Signal
et SignalProducer
sont deux entités différentes et nous devons lift
sur SignalProducer
pour pouvoir composer ce qui est produit avec des instances de Signal
. Les deux entités ont leurs propres opérateurs. Ainsi, lorsque vous devez mélanger des objets, vous devez vous assurer qu'un opérateur donné est disponible, de l'autre côté, vous oubliez les observables chaud/froid.
À propos de cette partie, Colin Eberhardt l'a bien résumé:
En regardant l’API actuelle, les opérations sur les signaux sont principalement axées sur l’événement "next", ce qui vous permet de transformer les valeurs, d’éviter, de retarder, de combiner et d’observer sur différents threads. Considérant que l’API du producteur de signal est principalement concernée par les événements du cycle de vie du signal (terminé, erreur), avec des opérations incluant ensuite, flatMap, takeUntil et catch.
RAC a également le concept de Action
et Property
, le premier est un type permettant de calculer les effets secondaires, principalement relatifs à l'interaction utilisateur, le second est intéressant lorsqu'il s'agit d'observer une valeur pour effectuer une tâche lorsque la valeur a modifié. Dans RxSwift, la Action
est à nouveau traduite en Observable
, ce qui est bien illustré dans RxCocoa
, une intégration de primitives Rx pour iOS et Mac. Le Property
du RAC peut être traduit en Variable
(ou BehaviourSubject
) dans RxSwift.
Il est important de comprendre que Property
/Variable
est le moyen par lequel nous devons relier le monde impératif à la nature déclarative de la programmation réactive. Il est donc parfois fondamental de traiter les bibliothèques tierces ou les fonctionnalités essentielles de la programmation. l'espace iOS/Mac.
RAC et RxSwift sont deux bêtes complètement différentes, la première a une longue histoire dans l’espace Cocoa et beaucoup de contributeurs, la dernière est assez jeune, mais repose sur des concepts qui se sont révélés efficaces dans d’autres langages tels que Java, JS ou. .NET. La décision sur ce qui est le mieux est de préférence. RAC déclare que la séparation entre observable chaud/froid était nécessaire et qu’il s’agit de la caractéristique essentielle du cadre, RxSwift indique que leur unification est meilleure que la séparation; il s’agit là encore de la gestion des effets secondaires.
RAC 3.0 semble avoir introduit une complexité inattendue en plus du principal objectif de séparer les observables chaud/froid, comme le concept d'interruption, de scinder les opérateurs entre deux entités et d'introduire un comportement impératif comme start
pour commencer à produire des signaux. Pour certaines personnes, ces choses peuvent être une bonne chose à avoir ou même une fonctionnalité tueur, pour d'autres, elles peuvent être simplement inutiles ou même dangereuses. Une autre chose à retenir est que RAC essaie de suivre les conventions Cocoa autant que possible. Ainsi, si vous êtes un développeur expérimenté dans Cocoa, vous devriez sentir plus confortable à utiliser que RxSwift.
RxSwift, quant à lui, présente tous les inconvénients, comme les observables chaud/froid, mais aussi les avantages des extensions réactives. Passer de RxJS, RxJava ou Rx.Net à RxSwift est une chose simple, tous les concepts sont identiques, cela rend donc la recherche de matériel assez intéressante, peut-être que le même problème que vous rencontrez maintenant a été résolu par quelqu'un de RxJava et que la solution peut être réappliqué en tenant compte de la plate-forme.
Ce qui doit être choisi est certainement une question de préférence, d'un point de vue objectif est impossible de dire lequel est le meilleur. La seule façon de procéder consiste à renvoyer Xcode, à essayer les deux et à choisir celui avec lequel vous vous sentirez le plus à l'aise. Ce sont 2 implémentations de concepts similaires, essayant d'atteindre le même objectif: simplifier le développement logiciel.