[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