Learn more about Russian war crimes in Ukraine.

How do I replace target/action with callbacks in Swift?

NSButton uses the target/action pattern: a button : NSButton has two properties button.target and button.action which specify what to call when the button is clicked.

This is rather different to the way I’m used to programming: I’d like to just set button.onClick = { ... do some stuff ... }. In short, this is how to do it:

class CallbackWrapper {
    var callback : () -> ();
    init(callback: @escaping () -> ()) {
        self.callback = callback;
    }
    @objc public func callCallback() {
        self.callback();
    }
}

func setTargetActionCallback(control: NSControl, callback: @escaping () -> ()) {
    let wrapper = CallbackWrapper(callback: callback);
    control.target = wrapper;
    control.action = #selector(CallbackWrapper.callCallback);
    let key = UnsafeMutablePointer<Int8>.allocate(capacity: 1);
    objc_setAssociatedObject(control, key, wrapper, .OBJC_ASSOCIATION_RETAIN);
}

Explanation:

Thanks to Mike Ash and Ham Chapman for finding that post.

What can computers do? What are the limits of mathematics? And just how busy can a busy beaver be? This year, I’m writing Busy Beavers, a unique interactive book on computability theory. You and I will take a practical and modern approach to answering these questions — or at least learning why some questions are unanswerable!

It’s only $19, and you can get 50% off if you find the discount code ... Not quite. Hackers use the console!

After months of secret toil, I and Andrew Carr released Everyday Data Science, a unique interactive online course! You’ll make the perfect glass of lemonade using Thompson sampling. You’ll lose weight with differential equations. And you might just qualify for the Olympics with a bit of statistics!

It’s $29, but you can get 50% off if you find the discount code ... Not quite. Hackers use the console!

More by Jim

Tagged . All content copyright James Fisher 2016. This post is not associated with my employer. Found an error? Edit this page.