Это очень хороший вопрос. Сравнивать два мира очень сложно. 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. Дизайн с Observables в RxSwift должен быть создан с учетом того, являются ли они горячими или холодными, это может звучать как ненужная сложность, но как только вы поняли, как они работают (и снова горячее / холодное / теплое - это почти побочные эффекты при подписке / наблюдении) ) их можно приручить.
В обоих мирах концепция подписки в основном одинакова, есть одно небольшое отличие, которое внес RAC, и это interruptionсобытие, когда a Signalудаляется до отправки события завершения. Напомним, что оба имеют следующие виды событий:
Next, чтобы вычислить новое полученное значение
Error, чтобы вычислить ошибку и завершить поток, отписавшись от всех наблюдателей
Complete, чтобы отметить поток как завершенный, отписавшись от всех наблюдателей
RAC, кроме того interrupted, отправляет его, когда Signalон удаляется до того, как завершится правильно или с ошибкой.
Написание вручную
В RAC Signal/ SignalProducerявляются объектами только для чтения, ими нельзя управлять извне, то же самое для ObservableRxSwift. Чтобы превратить 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и SignalProducer2 разные сущности , и мы должны 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 и попробовать оба, и выбрать тот, с которым удобнее работать. Это две реализации схожих концепций, пытающиеся достичь одной и той же цели: упростить разработку программного обеспечения.