It seems that closures of compatible parameter and return types can't be cast( up or down ). I want to store arrays of callbacks in a Dictionary, where the key can be used to determine the type of the callback's parameter. Just casting won't do:
typealias AnyCallback = ( value: AnyObject )-> Void
typealias SpecializedCallback = ( value: UIView ) -> Void
let callback : SpecializedCallback =
{
( value: UIView ) in
println( value )
}
if let castCallback : AnyCallback = callback as? AnyCallback
{
// block never executed
println( "did cast callback" )
castCallback( value: self.view )
}
As a workaround, it is possible to wrap the callback in a generic class which will handle parameter type casting:
final class GenericCallback< T >
{
func executeCallback( value: Any? ) -> Void
{
if let specificValue = value as? T
{
specificCallback( value: specificValue )
}
}
init( callback: ( value: T? )->Void )
{
self.specificCallback = callback
}
private let specificCallback : ( value: T? )->Void
}
As executeCallback captures self, it can be added directly to an array of callbacks safely, removing the need to keep a reference to the wrapper:
typealias GenericCallbackType = ( value: Any? ) -> Void
var callbackArray : [ GenericCallbackType ] = []
let specializedCallback =
{
( value: UIView? ) -> Void in
println( value )
}
let wrappedCallback = GenericCallback( callback: specializedCallback )
callbackArray.append( wrappedCallback.executeCallback )
It works fine, but of course I'm in the market for a simpler solution should there be one...