从RACSignal迁移到ReactiveSwift或RAC5

时间:2017-04-18 15:47:27

标签: swift reactive-cocoa reactive racsignal reactive-swift

我是Swift的新手,这就是我为什么选择Reactive Cocoa v5或Reactive Swift的原因。

以前我在RAC 2.x上使用过RACSignal,我喜欢这样做:

- (RACSignal *)signalForGET:(NSString *)URLString parameters:(NSDictionary *)parameters {
  return [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
      AFHTTPRequestOperation *op = [self GET:URLString parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
          [subscriber sendNext:responseObject];
          [subscriber sendCompleted];
      } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
          [subscriber sendError:error];
      }];
      return [RACDisposable disposableWithBlock:^{
          [op cancel];
      }];
   }];
}

在这里我喜欢它取消一次性请求,我也可以通过在返回的信号上调用dispose方法来手动取消它。

我对Reactive Swift中的所有这些东西感到有点困惑,比如SignalProducers等。

请举例说明如何使用最新的Swift / ReactiveSwift / ReactiveCocoa版本实现相同的功能。 主要要求是能够在任何我想要的地方取消请求(或处置信号),并在处置时自动取消请求

1 个答案:

答案 0 :(得分:6)

了解SignalSignalProducer的重要一点是HotCold信号之间的区别。

基本上,Hot信号是一个不关心其观察者的信号。它发送它的值,无论它是否有一个,多个甚至没有观察者。最重要的是:新观察不会对信号造成副作用,每个新用户将获得与其他用户完全相同的事件(减去订阅前已经发生的事件!)!想想用户输入,传感器数据......(忽略启动/停止传感器等事情)。

根据我的经验,真正的Hot信号在实践中很少见。

相比之下,Cold信号是关注其观察者的信号 - 对Cold信号的每次订阅都可能产生副作用,订阅者会根据该副作用接收事件。因此,两个不同的观察者每次开始副作用并获得不同的事件集。

在RAC中,Cold信号由SignalProducer表示。您可能还会将SignalProducer视为信号工厂(因此得名) - start SignalProducer执行副作用并返回事件Signal发送。

这几乎就是你的代码片段所做的。

Disposable自RAC 2.x以来没有太大变化,你仍然可以使用它。您可能在创建SignalProducer时错过了如何使用它:

func producerForGET(urlString: String, parameters: [String: String]) -> SignalProducer<Data, NSError> {
    return SignalProducer<Data, NSError> { observer, disposable in
        let operation = GET(url: urlString, parameters: parameters, success: { operation, responseObject in
            observer.send(value: responseObject)
            observer.sendCompleted()
        }, failure: { error in
            observer.send(error: error)
        })

        disposable += {
            print("Disposed")
            operation.cancel()
        }
    }
}

以下是一个快速示例,如何使用它可以使用:

producerForGET(urlString: "Bla", parameters: [:])
    .start()    // Performs the request and returns a Signal
    .dispose()  // Runs the disposable block and cancels the operation