Итак, теперь с быстрым, ReactiveCocoa люди переписали его в версии 3.0 для быстрого
Кроме того, был создан еще один проект, называемый RxSwift.
Интересно, могут ли люди добавить информацию о том, каковы различия в дизайне/апи/философии двух фреймворков (пожалуйста, в духе SO, придерживайтесь вещей, которые верны, а не мнения о том, что является "лучшим", )
[Примечание для модов StackOverflow: этот вопрос имеет окончательные ответы, ответ - различия между двумя структурами. Я думаю, что он также очень по теме для SO]
Чтобы начать, мое первоначальное впечатление от чтения их ReadMe:
Это очень хороший вопрос. Сравнение двух миров очень сложно. Rx - это порт того, что Reactive Extensions находится на других языках, таких как С#, Java или JS.
Реактивный Cocoa был вдохновлен функционально-реактивным программированием, но в последние месяцы также был отмечен как вдохновленный реактивными расширениями. Результатом является структура, которая разделяет некоторые вещи с Rx, но имеет имена с источником в FRP.
Первое, что нужно сказать, - это то, что ни RAC, ни RxSwift не являются реализациями функционального реактивного программирования, согласно определению конуса концепции. С этого момента все можно свести к тому, как каждая структура обрабатывает побочные эффекты и несколько других компонентов.
Расскажите о сообществе и метатехнике:
Теперь настало время для техник.
RAC 3.0 имеет 2 основных объекта, Signal
и SignalProducer
, первый публикует события независимо от того, подключен ли абонент или нет, второй требует start
для фактического получения сигналов/событий. Этот дизайн был создан, чтобы отделить утомительную концепцию горячих и холодных наблюдаемых, которая стала источником путаницы для многих разработчиков. Вот почему различия могут быть уменьшены до того, как они управляют побочными эффектами.
В RxSwift Signal
и SignalProducer
переводится на Observable
, это может показаться запутанным, но эти 2 сущности на самом деле одно и то же в мире Rx. Дизайн с Observable
в RxSwift должен быть создан, учитывая, что они горячие или холодные, это может звучать как ненужная сложность, но как только вы поняли, как они работают (и снова горячий/холодный/теплый - это только побочные эффекты при подписке/наблюдение) их можно приручить.
В обоих мирах концепция подписки в основном одна и та же, существует одна небольшая разница, которую RAC представляет и является событием interruption
, когда Signal
удаляется до того, как событие завершения было отправлено.
Напомним, что они имеют следующие события:
Next
, чтобы вычислить новое полученное значениеError
, чтобы вычислить ошибку и завершить поток, отменив подписку на всех наблюдателейComplete
, чтобы отметить поток как завершенную отмену подписки на всех наблюдателейКроме того, RAC имеет interrupted
, который отправляется, когда Signal
располагается до завершения либо с ошибкой, либо с ошибкой.
В RAC, Signal
/SignalProducer
являются объектами только для чтения, они не могут управляться извне, то же самое для Observable
в RxSwift. Чтобы превратить Signal
/SignalProducer
в объект, способный к записи, вы должны использовать функцию pipe()
для возврата элемента, управляемого вручную. В пространстве Rx это другой тип, называемый Subject
.
Если концепция чтения/записи звучит незнакомо, можно сделать приятную аналогию с Future
/Promise
. A Future
является заполнителем только для чтения, например Signal
/SignalProducer
и Observable
, а Promise
может выполняться вручную, например, для pipe()
и Subject
.
Этот объект очень похож в обоих мирах, те же концепции, но RAC является последовательным, вместо этого RxSwift имеет также параллельные планировщики.
Состав - ключевая особенность реактивного программирования. Составляющие потоки суть сущности обеих фреймворков, в RxSwift их также называют последовательностями.
Все наблюдаемые объекты в RxSwift имеют тип ObservableType
, поэтому мы создаем экземпляры Subject
и Observable
с теми же операторами без каких-либо дополнительных проблем.
В RAC-пространстве Signal
и SignalProducer
являются 2 разными объектами, и мы должны lift
на SignalProducer
, чтобы иметь возможность составлять то, что создается с экземплярами Signal
. У двух сущностей есть свои собственные операторы, поэтому, когда вам нужно смешивать вещи, вы должны убедиться, что есть определенный оператор, с другой стороны вы забыли о горячих/холодных наблюдаемых.
Об этой части Colin Eberhardt подвел итог:
Глядя на текущий 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 - это 2 полных разных зверя, первый имеет длинную историю в пространстве Cocoa и много участников, последний довольно молод, но полагается на концепции, которые оказались эффективными на других языках как Java, JS или .NET. Решение о том, что лучше, предпочтительнее. RAC заявляет, что разделение горячей/холодной наблюдаемой было необходимым, и это основная особенность структуры, RxSwift говорит, что объединение их лучше, чем разделение, опять же это просто о том, как управлять/выполнять побочные эффекты.
RAC 3.0, похоже, внедрил некоторую неожиданную сложность поверх главной цели разделения горячих/холодных наблюдаемых, таких как концепция прерывания, разделение операторов между двумя объектами и введение некоторого императивного поведения, такого как start
, для начала генерации сигналов. Для некоторых людей это может быть хорошей вещью, чтобы иметь или даже функцию убийцы, для некоторых других они могут быть просто лишними или даже опасными. Еще одна вещь, которую следует помнить, заключается в том, что RAC пытается как можно больше поддерживать соглашения Cocoa, поэтому, если вы опытный Cocoa Dev, вам следует чувствовать себя более комфортно, чтобы работать с ним чем RxSwift.
RxSwift, с другой стороны, живет со всеми минусами, такими как горячие/холодные наблюдаемые, но также и хорошие вещи из Reactive Extensions. Переход от RxJS, RxJava или Rx.Net к RxSwift - это просто, все концепции одинаковы, поэтому это делает поиск материала довольно интересным, может быть, с той же проблемой, с которой вы сейчас сталкиваетесь, был решен кем-то в RxJava и решением может быть повторно применена с учетом платформы.
Кто должен быть выбран, определенно является вопросом предпочтения, с объективной точки зрения невозможно сказать, какой из них лучше. Единственный способ - запустить Xcode и попробовать оба из них и выбрать тот, с которым вам удобнее работать. Это две реализации аналогичных концепций, стремящихся достичь той же цели: упрощение разработки программного обеспечения.
NoError
) в самих типах потоков: Signal<T, E: ErrorType>
или Observable<T>
. Это, а также разделение на «горячие» и «холодные» предоставляет во время компиляции увеличенный объем информации, которого у вас просто нет в RxSwift
.