【问题标题】:ReactiveCocoa subscribeNext for Optionals in SwiftReactiveCocoa subscribeNext 用于 Swift 中的 Optionals
【发布时间】:2015-09-21 03:11:30
【问题描述】:

我在RACSignal 上为许多常见的 ReactiveCocoa 操作写了一个扩展,mapfiltersubscribeNext,以便我可以在回调块中显式指定类型。 map 变成 mapAsfilter 变成 filterAssubscribeNext 变成 subscribeNextAs(等等)

func subscribeNextAs<T>(nextClosure:(T) -> ()) -> RACDisposable! {
   return self.subscribeNext {
        (next) -> () in
        if let nextAsT = next as? T {
            nextClosure(nextAsT)
        }
    }
}

然而,我注意到的一个问题是可选值没有传递给nextClosure,这是正确的,因为if let nextAsT 失败了。

我如何重写这个扩展函数,以便subscribeNextAs 允许我同时转换可选和非可选?

例子:

RACObserve(someObject, potentiallyOptionalTitle).subscribeNextAs({
    (next: String?) in
})
RACObserve(someObject, nonOptionalTitle).subscribeNextAs({
    (next: String) in
})

【问题讨论】:

    标签: ios swift reactive-cocoa


    【解决方案1】:

    您需要为nextClosure 参数指定泛型类型的可选性。在您的情况下,您可以将通用 subscribeNext 定义为:

    func subscribeNextAs<T>(nextClosure:(T!) -> ()) -> RACDisposable {
       return self.subscribeNext {
            (next) -> () in
               nextClosure(next != nil ? next as! T : nil)
        }
    }
    

    这里的缺点是可选性是隐藏的,这意味着您将无法在编译时保证您是否正确处理了 nil 值。 你必须小心不要在你不期望的地方传递 nil 值。

    另一种选择是升级到 RAC 4.x 并使用通用 Signal&lt;T&gt;,但它仍处于 Alpha 阶段,因此如果您要发布到 prod,请不要这样做。

    【讨论】:

      【解决方案2】:

      subscribeNext 采用 (AnyObject!)-&gt;Void 类型的闭包。此 AnyObject! 无法转换为 String?。在游乐场尝试这段代码:

      let str: String? = "1"
      str is String? // true
      
      let anyObjStr: AnyObject? = "1"
      anyObjStr is String? // false, not the same type
      anyObjStr is String // true, the unwrapped value can be cast to String
      anyObjStr is NSString // true
      

      要解决这个问题,你可以添加一个带有可选参数的方法的重载:

      func subscribeNextAs<T>(nextClosure:(T?) -> ()) -> RACDisposable! {
          return self.subscribeNext {
              (next) -> () in
              if let unwrapped = next {
                  if let nextAsT = unwrapped as? T {
                      nextClosure(nextAsT)
                  }
              } else {
                  nextClosure(nil)
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多