Создать сигнал, который испускает один объект, а затем завершает?

С RxSwift я бы сделал Observable.just(1) который будет излучать 1 затем выброс завершен.

Похоже, что с RAC2 вы могли бы сделать: [RACSignal return:@1]

Как мне это сделать с RAC3?

Чтобы быть более понятным... Я ищу способ создать RAC3 Signal это производит одно жестко закодированное значение. Как бы я это сделал? (SignalProducer(value: 1) не работает таким образом.)

2 ответа

Решение

Прочитав обсуждение, я думаю, что ответ Шарлотты Тортореллы остается верным: вы достигаете требуемого поведения с SignalProducer(value: 1).

Я думаю, что проблема заключается в недопонимании того, что Signal а также SignalProducer являются.

Как описано здесь, Signal в ReactiveSwift это горячий RACSignal в RAC 2.0 или Observable в Rx, и SignalProducer в ReactiveSwift это простуда RACSignal в RAC 2.0 или Observable в Rx. Это намеренное отклонение от других реактивных структур, а также от RAC < 3,0.

Это означает, что у вас, скорее всего, есть метод, который принимает простуду RACSignal или же Observable так как вы хотите, чтобы это срабатывало для каждого подписчика.

Так что, если вы хотите конвертировать код RAC 2.0, это ожидает Signal или же Observable, вам нужно будет изменить его, чтобы взять SignalProducer в RAC >= 3,0.

В качестве иллюстрации возьмем этот пример в ObjC и RAC 2.0:

-(void)observeSignal:(RACSignal *)signal
{
    [signal subscribeNext:^(NSNumber *x) {
        NSLog(@"Next: %@", x);
    } completed:^{
        NSLog(@"Completed");
    }];
}

Вызов этого метода так

RACSignal *signal = [RACSignal return:@(1)];
[self observeSignal:signal];
[self observeSignal:signal];

(дважды для иллюстрации поведения в каждой подписке) напечатает

Next: 1
Completed
Next: 1
Completed

В Swift и с ReactiveCocoa 5.0 эквивалентная реализация может выглядеть следующим образом

func observe(produer: SignalProducer<Int, NoError>) {
    produer.start { event in
        switch event {
        case .value(let value):
            print("Next: \(value)")
        case .completed:
            print("Completed")
        default:
            break
        }
    }
}

Называется так

let producer = SignalProducer<Int, NoError>(value: 1)
observe(produer: producer)
observe(produer: producer)

он выдает тот же результат

Next: 1
Completed
Next: 1
Completed

Быстрая версия может выглядеть немного объемнее, но если вам нужна только Next / value События они выглядят более или менее одинаково. Обратите внимание, что вам нужно start продюсер вместо просто observe сигнал.

Итак, в заключение:

Вы правы, нет никакого способа предоставить эквивалент, если вы ожидаете Signal, Для эквивалентной реализации вам нужно будет изменить свою функцию, чтобы SignalProducer, SignalProducer равносильно простуде Signal который будет срабатывать для каждого подписчика.

RAC 3 и выше использует конструктор.

SignalProducer(value: 1)

Другие вопросы по тегам