Makalele
Makalele

Reputation: 7531

Objective-C selector deprecated replacement

As many question have shown recently, literal selectors are deprecated. There's a quick fix, which works fine if selector is just in that one class.

But consider this example (I have a lot more code; this is a simplified example):

static func createMenuButton(controller:UIViewController) -> UIBarButtonItem {
    let menuButton = UIButton(frame: CGRectMake(0, 0, 22, 22))
    menuButton.addTarget(controller, action: Selector("menuButtonClicked:"), forControlEvents:.TouchUpInside)
    let menuButtonContainer = UIView(frame: menuButton.frame)
    menuButtonContainer.addSubview(menuButton)
    let menuButtonItem = UIBarButtonItem(customView: menuButtonContainer)
    return menuButtonItem
}

This utility method gives me good functionality to be used in various view controllers. Because of its multiple usage, I'd have to copy it to each view controller to use the new #selector syntax. But Apple, why deprecate more dynamic method? I guess in new release they'll just remove it, like i++, i-- and C-style for loops (but they can be easily replaced, though I don't get why they remove them). Are there any workarounds to keep this approach working in future releases? Each new release breaks all my projects syntax.

Upvotes: 1

Views: 643

Answers (1)

Aaron Brager
Aaron Brager

Reputation: 66252

why deprecate more dynamic method?

From the proposal to make this change:

we free the developer from having to do the naming translation manually and get static checking that the method exists and is exposed to Objective-C.

For your approach, you could make a protocol that indicates a certain method is present:

@objc protocol MenuButtonClickable {
    func menuButtonClicked()
}

In your view controller, add this method:

extension MyViewController : MenuButtonClickable {
    func menuButtonClicked() {
        // do something
    }
}

Then update your method signature to use this protocol:

static func createMenuButton(controller:MenuButtonClickable) -> UIBarButtonItem {

Now the Swift compiler is guaranteed that controller has that method, so you'll be able to use the new #selector syntax.

And if you accidentally try to use this method on a view controller without this function, you'll get a compile-time error instead of a runtime error.

Upvotes: 2

Related Questions