ReactiveCocoa против RxSwift - плюсы и минусы?

256

Так что теперь с Swift, люди ReactiveCocoa переписали его в версии 3.0 для Swift

Также был запущен еще один проект под названием RxSwift .

Интересно, могли бы люди добавить информацию о том, каковы различия в дизайне / API / философии двух структур (пожалуйста, в духе SO придерживайтесь правдивых вещей, а не мнений о том, «что лучше»)

[Примечание для модов StackOverflow: на этот вопрос есть однозначные ответы, ответ заключается в различиях между двумя системами. Я думаю, что это также очень по теме для SO]

Для начала мое первоначальное впечатление от чтения их ReadMe:

  • Как человек, знакомый с «настоящим» C # Rx от Microsoft, RxSwift выглядит намного более узнаваемым.
  • ReactiveCococa, похоже, ушел в свое собственное пространство, представив новые абстракции, такие как Signals vs SignalProducers и Lifting. С одной стороны, это, кажется, проясняет некоторые ситуации (что является сигналом «Горячий против холодного»), но с другой стороны, это, кажется, увеличивает сложность структуры на много
Орион Эдвардс
источник
Ваш вопрос специально просит "мнения". Не могли бы вы перефразировать? Тогда я с радостью откажусь от своего закрытого голосования.
Sulthan
2
Вы можете избавиться от «добавить свое мнение», потому что различия являются фактами, а не мнениями. Тогда вам могут понравиться или не понравиться некоторые функции RAC / RxSwift, но различия кристально ясны.
bontoJR
1
хахаха, хороший ход по поводу "примечания к модам"!
Минг Йоу
1
Переименуйте вопрос: Разница между ReactiveCocoa и RxSwift. Я думаю, что все станет «фактом», и этот вопрос унаследован.
августа
1
Даже решение начинается с «Это очень хороший вопрос». : |
Юлиан Онофрей

Ответы:

419

Это очень хороший вопрос. Сравнивать два мира очень сложно. 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 и попробовать оба, и выбрать тот, с которым удобнее работать. Это две реализации схожих концепций, пытающиеся достичь одной и той же цели: упростить разработку программного обеспечения.

bontoJR
источник
24
Это отличное объяснение, @ junior-b! Стоит также отметить, что RAC кодирует информацию о типах (включая отсутствие ошибок благодаря NoError) в самих типах потоков: Signal<T, E: ErrorType>против Observable<T>. Это, так же как и разделение «горячий / холодный», обеспечивает увеличение объема информации во время компиляции, которой у вас просто нет RxSwift.
NachoSoto
3
Привет @nachototo, спасибо за доброе слово. Я думаю, что предложенное дополнение не очень хорошо вписывается в сравнение по реактивному программированию. Это определенно хорошее дополнение со стороны RAC, но для меня RP - это упрощение программирования потока данных, и важными факторами являются: обработка ошибок, асинхронные вычисления, управление побочными эффектами и составление. С точки зрения разработчика, это кажется хорошей особенностью, это для выяснения типа ошибок в коде, это не очень улучшает аспект обработки ошибок в фреймворке, это, конечно, мое скромное мнение.
bontoJR
3
Стоит отметить, что на данный момент не хватает достойных учебных пособий по RAC, однако есть несколько отличных примеров проектов для RxSwift, которые были для меня решающими.
Вадим Булавин
1
ReactiveCocoa была хороша, пока они не представили бесплатные функции SignalProducer, общие с ошибкой. Я изучаю RxSwift и получаю такой же опыт при работе с RxKotlin, RxJS
onmyway133