你实际上离那里很近。
但是你不能有RACSignal
s of CGPoint
s,因为CGPoint
它不是引用类型。通常,在 ReactiveCocoa 2 的世界中,您可以通过显式地装箱和拆箱类型来解决这个问题,例如NSValue
并进行相当多的转换:
panRecognizer.rac_gestureSignal()
.map({ [unowned self] (pgr: AnyObject!) -> NSValue! in
let pgr = pgr as! UIPanGestureRecognizer
return NSValue(CGPoint: pgr.locationInView(self.someUiView))
}).subscribeNext({[unowned self] locationValue in
let location = locationValue.CGPointValue
self.someNetworkDelegate.updatePosition(location)
})
但是,通过将 转换RACSignal
为 a SignalProducer
,您可以使用所需的漂亮类型。这样做......很麻烦,所以我使用以下助手:
extension SignalProducer {
func castSignal<T>() -> SignalProducer<T, Error> {
return self.map({ $0 as! T })
}
func cantError() -> SignalProducer<Value, NoError> {
// If we inline this, Swift will try to implicitly return the fatalError
// expression. If we put an explicit return to stop this, it complains
// it can never execute. One is an error, the other a warning, so we're
// taking the coward's way out and doing this to sidestep the problem.
func swallowError(error: Error) -> SignalProducer<Value, NoError> {
fatalError("Underlying signal errored! \(error)")
}
return self.flatMapError(swallowError)
}
}
extension RACSignal {
func cast<T>() -> SignalProducer<T, NoError> {
return self.toSignalProducer().cantError().map({ $0! }).castSignal()
}
}
显然,如果您要转换可能出错的信号,则需要不同的助手,但这对于本示例非常有效。
有了这些,您可以像这样编写代码:
self.reportTapRecognizer.rac_gestureSignal().cast()
.map({ [unowned self] (pgr: UIPanGestureRecognizer) -> CGPoint in
return pgr.locationInView(self.someUiView)
}).startWithNext({ [unowned self] location in
self.someNetworkDelegate.updatePosition(location)
})
这基本上就是你上面写的方式。请注意,map
调用中需要类型注释,以便cast
可以正确推断其返回类型。