[swift-evolution] Type-safe selectors

Kevin Ballard kevin at sb.org
Sat Dec 5 00:23:33 CST 2015

On Fri, Dec 4, 2015, at 06:45 PM, Joe Groff wrote:

> Why couldn't this be covered by overloads? It's unlikely we'd be able
> to import selectors from Objective-C to specific types because of this
> and other reasons, so we'd still need an untyped Selector type, but we
> could easily provide well-typed overloads in Swift overlays that
> convert from typed selectors to untyped.

This can only be covered by overloads when the selector is passed to a
function. So that would work for target/action in iOS, where you use
addTarget(_:action:forControlEvents:). But it won't work for OS X, where
target/action is exposed as two independent properties, because you
can't overload properties.

On Fri, Dec 4, 2015, at 06:46 PM, Michel Fortin wrote:

> Implicit conversions cannot happen safely in the direction SubType to BaseType for
> the arguments, including the target object. That makes Joe Groff's
> approach the only type-safe solution: make an extension of the base
> object and generate a method that does what you want. Which means that
> instead of this:
> 	view.action = MyObject.doSomething
> you could write this:
> 	view.action = { (target: AnyObject) in {
> 		(target as! MyObject).doSomething()
> 	}
> ...which is safe. Maybe the compiler should just auto-generate that
> boilerplate for you.

How can you write that? A @convention(selector) can't actually contain
any executable code, because there's nowhere to store that code (since
the runtime representation of a @convention(selector) is just a SEL,
because the message dispatch is done strictly with the SEL and the
receiver object). So you can't make this type-safe on the receiver,
because the object that receives the selector is by definition the
receiver, and there's no way to force this to be the same type as the
type you generated the selector from.

-Kevin Ballard

More information about the swift-evolution mailing list