[swift-evolution] Type-safe selectors

Joe Groff jgroff at apple.com
Sat Dec 5 09:17:30 CST 2015


> On Dec 5, 2015, at 4:30 AM, Michel Fortin <michel.fortin at michelf.ca> wrote:
> 
> 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 [...]
> 
> Like this:
> 
> 	view.action = "_doSomething_UniqueSelector1234_currentModuleName_blahblah"
> 
> 	extension NSObject {
> 		func _doSomething_UniqueSelector1234_currentModuleName_blahblah() {
> 			let target = self
> 			(target as! MyObject).doSomething()
> 		}
> 	}
> 
> (Joe Groff suggested it first.) This simply assumes the receiver will derive from NSObject. You also need to set a non-nil target. And note that the closure is context-free, meaning you can't capture variables with it.
> 
> I wonder how many methods like this you can add to NSObject before it starts to impact objc_msgSend dispatch performance...

The receiver doesn't have to inherit NSObject. Pure Swift classes on Darwin are id-compatible and can have categories as well.

-Joe


More information about the swift-evolution mailing list