Это очень хороший вопрос. Сравнивать два мира очень сложно. Rx - это порт Reactive Extensions на других языках, таких как C #, Java или JS.
Реактивное Какао было вдохновлено Функциональным Реактивным Программированием , но в последние месяцы было также отмечено, что вдохновлено также Реактивными Расширениями . Результатом является структура, которая разделяет некоторые вещи с Rx, но имеет имена с корнями в FRP.
Первое, что нужно сказать, это то, что ни RAC, ни RxSwift не являются реализациями функционально-реактивного программирования , согласно определению концепции Conal . С этого момента все может быть сведено к тому, как каждая структура обрабатывает побочные эффекты и несколько других компонентов.
Давайте поговорим о сообществе и мета-технологиях :
- RAC - это трехлетний проект, родившийся в Objective-C, который позже был перенесен в Swift (с мостами) для версии 3.0, после того как полностью прекратил работу над Objective-C.
- RxSwift - проект, рассчитанный на несколько месяцев, и сейчас он, кажется, набирает обороты в сообществе. Одна вещь, которая важна для RxSwift, это то, что она находится в организации ReactiveX и что все другие реализации работают одинаково, изучение того, как работать с RxSwift, сделает работу с Rx.Net, RxJava или RxJS простой задачей и просто вопросом. синтаксиса языка. Я мог бы сказать, что на основе философии учиться один раз, применять везде .
Теперь пришло время для технических вещей.
Производящие / Наблюдатели
RAC 3.0 имеет 2 основных объекта, Signal
и SignalProducer
первый публикует события независимо от того, подключен подписчик или нет, второй требует start
фактического создания сигналов / событий. Этот дизайн был создан для того, чтобы отделить утомительную концепцию горячих и холодных наблюдаемых, которая была источником путаницы для многих разработчиков. Вот почему различия могут быть сведены к тому, как они справляются с побочными эффектами .
В RxSwift, Signal
и SignalProducer
переводится как Observable
, это может показаться странным, но эти два объекта на самом деле одно и то же в мире Rx. Дизайн с Observable
s в RxSwift должен быть создан с учетом того, являются ли они горячими или холодными, это может звучать как ненужная сложность, но как только вы поняли, как они работают (и снова горячее / холодное / теплое - это почти побочные эффекты при подписке / наблюдении) ) их можно приручить.
В обоих мирах концепция подписки в основном одинакова, есть одно небольшое отличие, которое внес RAC, и это interruption
событие, когда a Signal
удаляется до отправки события завершения. Напомним, что оба имеют следующие виды событий:
Next
, чтобы вычислить новое полученное значение
Error
, чтобы вычислить ошибку и завершить поток, отписавшись от всех наблюдателей
Complete
, чтобы отметить поток как завершенный, отписавшись от всех наблюдателей
RAC, кроме того interrupted
, отправляет его, когда Signal
он удаляется до того, как завершится правильно или с ошибкой.
Написание вручную
В RAC Signal
/ SignalProducer
являются объектами только для чтения, ими нельзя управлять извне, то же самое для Observable
RxSwift. Чтобы превратить Signal
/ SignalProducer
в объект с возможностью записи, вы должны использовать pipe()
функцию для возврата элемента, управляемого вручную. В пространстве Rx это называется другим типом Subject
.
Если концепция чтения / записи звучит незнакомо, можно провести хорошую аналогию с Future
/ Promise
. A Future
- это заполнитель только для чтения, например Signal
/, SignalProducer
и Observable
, с другой стороны, a Promise
можно выполнить вручную, например, для pipe()
и Subject
.
Планировщики
Эта сущность во многом схожа в обоих мирах, одни и те же понятия, но RAC только для последовательного интерфейса, вместо этого RxSwift поддерживает также параллельные планировщики.
Сочинение
Композиция является ключевой особенностью реактивного программирования. Составление потоков - это сущность обеих платформ, в RxSwift их также называют последовательностями .
Все наблюдаемые объекты в RxSwift относятся к типу ObservableType
, поэтому мы создаем экземпляры Subject
и Observable
с одинаковыми операторами, без каких-либо дополнительных забот.
На RAC пространстве, Signal
и SignalProducer
2 разные сущности , и мы должны lift
на , SignalProducer
чтобы иметь возможность создавать то , что производится с экземплярами Signal
. У этих двух объектов есть свои собственные операторы, поэтому, когда вам нужно смешать вещи, вы должны убедиться, что определенный оператор доступен, с другой стороны вы забываете о горячих / холодных наблюдаемых.
Об этой части Колин Эберхардт подвел итог:
Глядя на текущий API, сигнальные операции в основном сосредоточены на «следующем» событии, что позволяет вам преобразовывать значения, пропускать, задерживать, объединять и наблюдать в разных потоках. Принимая во внимание, что API производителя сигналов в основном связан с событиями жизненного цикла сигнала (завершено, ошибка), с такими операциями, как then, flatMap, takeUntil и catch.
дополнительный
RAC также имеет концепцию Action
и Property
, первый тип является типом для вычисления побочных эффектов, главным образом связанных с взаимодействием с пользователем, последний интересен при наблюдении значения для выполнения задачи, когда значение изменилось. В RxSwift это Action
снова переводит в Observable
, как это хорошо показано RxCocoa
, интеграцию примитивов Rx для iOS и Mac. RAC Property
могут быть переведены в Variable
(или BehaviourSubject
) в RxSwift.
Важно понимать, что Property
/ Variable
это способ, которым мы должны связать императивный мир с декларативной природой реактивного программирования, поэтому иногда это фундаментальный компонент при работе со сторонними библиотеками или основными функциями пространства iOS / Mac.
Вывод
RAC и RxSwift - это два совершенно разных зверя, первый имеет долгую историю в пространстве Какао и много участников, последний довольно молод, но опирается на концепции, доказавшие свою эффективность в других языках, таких как Java, JS или .СЕТЬ. Решение о том, что лучше, находится на предпочтении. RAC заявляет, что разделение наблюдаемых в горячем и холодном режимах было необходимо, и это является основной особенностью платформы, RxSwift говорит, что их объединение лучше, чем разделение, опять же, речь идет о том, как побочные эффекты управляются / выполняются.
RAC 3.0, кажется, представил некоторую неожиданную сложность поверх основной цели разделения горячих / холодных наблюдаемых, таких как концепция прерывания, разделения операторов между двумя объектами и введения некоторого императивного поведения, например, start
для начала генерации сигналов. Для некоторых людей эти вещи могут быть полезны или даже убийственны, для некоторых других они могут быть просто ненужными или даже опасными. Еще одна вещь, которую следует помнить, это то, что RAC старается максимально соответствовать соглашениям о Какао, поэтому, если вы опытный разработчик Cocoa, вам должно быть удобнее работать с ним, а не с RxSwift.
RxSwift, с другой стороны, живет со всеми недостатками, такими как горячие / холодные наблюдаемые, но также и с хорошими вещами из Reactive Extensions. Переход от RxJS, RxJava или Rx.Net к RxSwift - это простая вещь, все концепции одинаковы, так что это делает поиск материала довольно интересным, возможно, та же проблема, с которой вы сталкиваетесь сейчас, была решена кем-то в RxJava, и решение может быть повторно применен с учетом платформы.
Какой из них должен быть выбран, безусловно, является вопросом предпочтения, с объективной точки зрения невозможно сказать, какой из них лучше. Единственный способ - запустить Xcode и попробовать оба, и выбрать тот, с которым удобнее работать. Это две реализации схожих концепций, пытающиеся достичь одной и той же цели: упростить разработку программного обеспечения.