Sorry for the weird title. Here's a toy sketch of my code:
extension UIControl {
func makeHolder() -> ControlHolder {
ControlHolder(control: self)
}
}
struct ControlHolder {
let control : UIControl
init(control: UIControl) {
self.control = control
}
func retrieve() -> UIControl {
return self.control
}
}
I admit this is a toy reduction, and I don't like when people do that, but it illustrates the syntactical issue perfectly, so let's go with it.
Okay, so we have an extension on UIControl that is a method that returns a wrapper object. Now, the problem is this:
let holder = UISwitch().makeHolder()
let output = holder.retrieve()
The result, output, is typed as UIControl, obviously. But that isn't what I want. I want it to be typed as UISwitch, because I started with a UISwitch. OK, so that sounds like a generic. The problem is, I can't figure out how to make that generic.
It's easy, I think, to make ControlHolder a generic:
struct ControlHolder<T:UIControl> {
let control : T
init(control: T) {
self.control = control
}
func retrieve() -> T {
return self.control
}
}
I'm pretty sure I've got that part right. But then how do I write the extension declaration in such a way as to resolve that generic to the actual type of self, the UIControl on which makeHolder is called?
I tried introducing a generic to the extension, obeying the compiler until I got it to compile:
extension UIControl {
func makeHolder<T>() -> ControlHolder<T> {
ControlHolder<T>(control: self as! T)
}
}
But that's pretty silly, and output is still typed as UIControl.
Obviously I can add another parameter passing the type explicitly into makeHolder and thus resolving it:
extension UIControl {
func makeHolder<T>(ofType: T.Type) -> ControlHolder<T> {
ControlHolder<T>(control: self as! T)
}
}
Now when I call makeHolder I pass in the type:
let holder = UISwitch().makeHolder(ofType: UISwitch.self)
let output = holder.retrieve()
And now of course output is typed as UISwitch. But this is idiotic! I want the extension to just know that the type is UISwitch, because I'm calling makeHolder on a UISwitch.
I feel like I'm coming at this all wrong. Maybe someone can straighten me out? Or am I aiming for something that's just impossible?