【问题标题】:Migrate from RACSignal to ReactiveSwift or RAC5从 RACSignal 迁移到 ReactiveSwift 或 RAC5
【发布时间】:2017-04-18 15:47:27
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

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

    这几乎就是你的 sn-p 所做的。

    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
    

    【讨论】:

    • 谢谢兄弟。这与我在这里询问之前所尝试的基本相同,但是因为 Xcode 自动完成无法识别这种信号生成器初始化程序而感到困惑。另外我不明白为什么它不允许在这里使用错误类型来处理错误......但是非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 2019-05-14
    • 2012-02-28
    • 2013-12-24
    • 2010-10-20
    相关资源
    最近更新 更多