ReactiveCocoa subscribeNext for Swift中的Optionals

时间:2015-09-21 03:11:31

标签: ios swift reactive-cocoa

我在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
})

2 个答案:

答案 0 :(得分:0)

您需要为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<T>但它仍然在Alpha中,所以如果你要发布prod,请不要这样做。

答案 1 :(得分:0)

<div id='post-body'> Lorem ipsum dolor set <img src='any URL'> </div> 采用subscribeNext类型的闭包。此(AnyObject!)->Void无法转换为AnyObject!。在playgroud中尝试此代码:

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