WedX - журнал о программировании и компьютерных науках

Буферизация сигналов перед появлением определенного сигнала

Интересно, возможно ли накапливать результаты сигналов, происходящих между nexts определенного сигнала. Похожий на

[[[RACSignal
    combineLatest:@[signal1, signal2, signal3]]
    takeUntil:signal4]
    subscribeNext:^(id x) {
        // ...
    }];

Но не завершая после первых signal4 next.

Сценарий, с которым я работаю, заключается в том, что у меня есть viewController1, представляющий viewController2. viewController2 позволяет пользователю изменять object, что влияет на данные, представленные в viewController1. Сейчас я выставляю objectChangedSignal на viewController2 и слушаю с viewController1.

Однако я хотел бы получать изменения object непосредственно от viewController1, но только после того, как он выдаст сигнал viewWillAppear, и только если изменения произошли после viewWillDisappear из viewController1.

Надеюсь, это имеет смысл, спасибо.


Ответы:


1

Один из способов буферизации значений — использовать -[RACSignal collect], который собирает их в массив до тех пор, пока сигнал не завершится:

[[[RACSignal combineLatest:@[ s1, s2, s3 ]]
    collect]
    takeUntil:s4]

Однако вы, вероятно, хотели, чтобы каждое значение передавалось отдельно в финальном сигнале, а не в виде массива значений. Вы можете использовать -[RACSignal flattenMap:], чтобы вернуть эти значения обратно в окончательный сигнал:

[[[[RACSignal combineLatest:@[ s1, s2, s3 ]]
    collect]
    takeUntil:s4]
    flattenMap:^(NSArray *collected) {

        return [[collected rac_sequence] signal];

    }]

А так как вы не хотите, чтобы ваш сигнал завершался после s4, вы можете использовать -repeat для повторной подписки после каждого раза, когда s4 отправляет значение. Если вы этого не сделаете, -takeUntil: приведет к завершению вашего сигнала, когда это произойдет.

[[[[[RACSignal combineLatest:@[ s1, s2, s3 ]]
    collect]
    takeUntil:s4]
    flattenMap:^(NSArray *collected) {

        return [[collected rac_sequence] signal];

    }]
    repeat]

Обратите внимание, что если какой-либо из комбинированных сигналов является холодным сигналом, повторная подписка приведет к тому, что их побочные эффекты будут проявляться дополнительное количество раз. Поэтому вам, возможно, придется преобразовать их в горячий сигнал путем их многоадресной рассылки (или комбинированного сигнала):

RACMulticastConnection *mc = [[RACSignal combineLatest:@[ s1, s2, s3 ]] publish];
RACDisposable *d = [mc connect];
[[[mc.signal
    takeUntil:s4]
    flattenMap:^(NSArray *collected) {

        return [[collected rac_sequence] signal];

    }]
    repeat]

Возможно, вам придется явно отказаться от подписки (удалив d), если в противном случае ваш сигнал будет жить бесконечно.

(Nota bene, этот код не проверен.)

24.02.2014
  • Спасибо за развернутый ответ! Но на самом деле это не работает так, как я себе представлял; скорее всего из-за плохого описания задачи: s1, s2 и s3 не обязательно сработают. Но если они это сделают, я хочу получить уведомление только после того, как s4 уволится. 25.02.2014
  • Если какой-либо из s1, s2 или s3 не отправляет значение, то -combineLatest: никогда не отправит значение — он ждет, пока каждый из переданных ему сигналов не отправит значение, прежде чем отправить кортеж значений. (С этим можно справиться, например, с помощью -startWith:.) Также звучит так, будто -[takeUntil:s4] — это не то, что вам нужно, так как это завершает сигнал, когда срабатывает s4. Возможно, вам нужна одна из -skipUntilBlock:, -skipWhileBlock: или -if:then:else: операций? 25.02.2014
  • Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]