我在RACSignal
上为很多常见的ReactiveCocoa操作map
,filter
,subscribeNext
编写了一个扩展名,以便我可以在回调中明确指定类型块。 map
成为mapAs
,filter
成为filterAs
,subscribeNext
成为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
})
答案 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