ReactiveCocoa против RxSwift - плюсы и минусы?
Так что теперь с Swift, люди ReactiveCocoa переписали его в версии 3.0 для Swift
Также был запущен еще один проект под названием RxSwift.
Интересно, могли бы люди добавить информацию о том, каковы различия в дизайне / API / философии двух структур (пожалуйста, в духе SO, придерживайтесь правдивых вещей, а не мнений о том, что является "лучшим")
[Примечание для модов Stackru: на этот вопрос НЕТ однозначных ответов, ответ заключается в различиях между двумя структурами. Я думаю, что это также очень по теме для SO]
Для начала мое первоначальное впечатление от чтения их ReadMe:
- Как человек, знакомый с "настоящим" C# Rx от Microsoft, RxSwift выглядит намного более узнаваемым.
- ReactiveCococa, похоже, ушел в свое собственное пространство, представив новые абстракции, такие как Signals vs SignalProducers и Lifting. С одной стороны, это, кажется, проясняет некоторые ситуации (что является сигналом "Горячий против холодного"), но с другой стороны, это, кажется, увеличивает сложность структуры на много
1 ответ
Это очень хороший вопрос. Сравнивать два мира очень сложно. 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
событие, когда Signal
удаляется до отправки события завершения. Напомним, что оба имеют следующие виды событий:
Next
, чтобы вычислить новое полученное значениеError
, чтобы вычислить ошибку и завершить поток, отписавшись от всех наблюдателейComplete
, чтобы отметить поток как завершенный, отписавшись от всех наблюдателей
RAC дополнительно имеет interrupted
который отправляется, когда Signal
располагается перед завершением либо правильно, либо с ошибкой.
Написание вручную
В RAC, Signal
/ SignalProducer
являются объектами только для чтения, ими нельзя управлять извне, то же самое для Observable
в RxSwift. Превратить Signal
/ SignalProducer
в объект для записи, вы должны использовать pipe()
функция для возврата элемента, управляемого вручную. На пространстве Rx это другой тип, называемый Subject
,
Если концепция чтения / записи звучит незнакомо, хорошая аналогия с Future
/ Promise
может быть сделано. Future
заполнитель только для чтения, например Signal
/ SignalProducer
а также Observable
с другой стороны, 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's 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, попробовать оба и выбрать тот, с которым удобнее работать. Это две реализации схожих концепций, пытающиеся достичь одной и той же цели: упростить разработку программного обеспечения.