3

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

以前我将 RACSignal 与 RAC 2.x 一起使用,我喜欢做这样的事情:

- (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 版本实现相同的功能。主要要求是能够在任何我想要的地方取消请求(或处置信号),并在处置时自动取消请求

4

1 回答 1

6

重要的是要了解Signaland和SignalsSignalProducer之间的区别。HotCold

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

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

相比之下,Cold信号是一个关心其观察者的信号 - 每个对Cold信号的订阅都可能执行副作用,并且订阅者接收基于该副作用的事件。因此,两个不同的观察者各自启动一次副作用并获得不同的事件集。

在 RAC 中,Cold信号由 表示SignalProducer。您可能还认为 aSignalProducer是信号的工厂(因此得名) - startaSignalProducer执行副作用并返回Signal发送事件的 a。

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

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
于 2017-04-18T17:19:43.557 回答