Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strongly typed selectors in swift

Tags:

ios

swift

cocoa

I wonder can we implement strongly typed selectors in swift? For example if i have a method named buttonTapped(sender: AnyObject) in my view controller later when we add that method as target to some button can we just say

button.addTarget(self, selector:ViewController.buttonTapped(self), forControlEvents: .TouchUpInside)
like image 666
mustafa Avatar asked Oct 19 '14 09:10

mustafa


1 Answers

Outdated. See Claus Jørgensen's answer for Swift 2.2+

There is no concept of "selector" in Swift. Ideally, closure should be used for such purpose.

What you really want is something like this

button.addAction(forControlEvents: .TouchUpInside) {
   // watch out for retain cycle, use weak or unowned accordingly
    ViewController.buttonTapped(self)
}

and you can have it with this code (untested, but it should give you a start point)

public class ClosureWrapper : NSObject
{
    let _callback : Void -> Void
    init(callback : Void -> Void) {
        _callback = callback
    }
    
    public func invoke()
    {
        _callback()
    }
}

var AssociatedObjectHandle: UInt8 = 0

extension UIControl
{
    public func addAction(forControlEvents events: UIControlEvents, withCallback callback: Void -> Void)
    {
        let wrapper = ClosureWrapper(callback)
        addTarget(wrapper, action:"invoke", forControlEvents: events)
        // as @newacct said in comment, we need to retain wrapper object
        // this only support 1 target, you can use array to support multiple target objects
        objc_setAssociatedObject(self, &AssociatedObjectHandle, wrapper, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
    }
}

and hopefully in the future release of SDK, similar methods takes closure instead of selectors will be added by Apple, so we don't need to implement them ourself.

like image 125
Bryan Chen Avatar answered Oct 07 '22 18:10

Bryan Chen