Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Properly Typed Selectors in Xcode 7.3 Beta 4

DZone's Guide to

Properly Typed Selectors in Xcode 7.3 Beta 4

Selectors can now be constructed from directly with the #selector expression.

· Mobile Zone
Free Resource

Discover how to focus on operators for Reactive Programming and how they are essential to react to data in your application.  Brought to you in partnership with Wakanda

How many times have you had some innocuous looking code like this:


    let button = UIButton(type: .InfoDark)
    button.addTarget(self, action: "showInfo", forControlEvents: .TouchDown)

...which compiles without a problem but throws a runtime error when the hapless user touches the button:


    Terminating app due to uncaught exception 'NSInvalidArgumentException', 

    reason: '-[__lldb_expr_20.SelectorDemo showInfo]: unrecognized selector 

    sent to instance 0x7ffb3a414ac0'

The runtime error is caused by Swift not being able to find the showInfo function or maybe there is a showInfo, but it expects an argument. The root cause is, of course, the action argument of addTarget is being passed the string literal showInfo rather than a properly typed object. 

Well, with Xcode 7.3 beta 4, that problem is resolved! Selectors can now be constructed from directly with the#selector expression. In practice, this means that if your code has a function that looks like this:

    func showInfo(button: UIButton)
    {
        print("showInfo(_:)", button.debugDescription)
    }

We can add a target to the button with the following syntax:

    let selector = #selector(showInfo(_:))

    button.addTarget(self, action: selector, forControlEvents: .TouchDown)

If showInfo takes no arguments...

    func showInfo()
    {
 print("one: showInfo()")
    }

...the syntax is slightly different:

    let selector = #selector(SelectorDemo.showInfo as (SelectorDemo) -> () -> ())

Either way, the great advantage is that if the method name doesn't exist or the arguments are different, we get an error at compile time rather than runtime:

    let selectorTwo = #selector(displayInfo(_:))

    // results in:


    Playground execution failed: SelectorPlayground.playground:20:37: error: use of unresolved     

    identifier 'displayInfo'

        let selector = #selector(displayInfo(_:))

                                 ^~~~~~~~~~~



I've created a small playground to demonstrate this new feature - it obviously needs Xcode 7.3 beta 4 - which is available at my GitHub repository.  Enjoy!

Learn how divergent branches can appear in your repository and how to better understand why they are called “branches".  Brought to you in partnership with Wakanda

Topics:
xcode

Published at DZone with permission of Simon Gladman, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}