0

I created a simple test to show what I am trying to do, sometimes we need to use some code that need to feed a selector and that selector need a function that have @objc, what I want and trying to do is deform the shape of code that I could bypass using @objc in front of function or more perfectly even deforming using selector also, basically I want avoid having selector or @objc in my codes, here is the example:

class MyTestAppClass {
    @objc func test() {
        print("Hello, world!")
    }
}

let test = NSMenuItem(title: "Test", action: #selector(MyTestAppClass.test), keyEquivalent: "t")

as you can see the NSMenuItem needs a selector and I have to responding it with a func that has @objc, so all my goal is avoiding selector in first place and if that is not possible trying to avoid using @objc, How can i do this? Is there any way for bypass those? Also this question is not trying to learn about basic of selector or @objc, it simply tries to find hacks for reaching the goal of avoiding them. I want my code looks more swiftier after bypassing #selector or @objc. Is there any option or space in coding that allow us for some maneuvers?

  • 3
    What's wrong with `@objc`? At the end of the day, `NSMenuItem` is an Objective-C API so you gotta expose your Swift functions to Objective-C *at some point*. – Sweeper Feb 13 '23 at 01:17
  • As I said I not trying to delete `@objc` from Swift, I am looking to deform the use case of it, maybe with creating an extension that do the job, some thing like that, in that way that I no dot have to use `@objc` again or selector anymore. –  Feb 13 '23 at 01:20
  • 1
    I see. In that case you can either subclass `NSMenuItem` and put the `@objc` methods in the subclass, and expose closures for other code to set, like [this answer](https://stackoverflow.com/a/38086405/5133585) does with `UIButton`. Alternatively, create an extension on `NSMenuItem` that adds an initialiser that takes closures, like [this answer](https://stackoverflow.com/a/49259126/5133585). Note how `objc_setAssociatedObject` is used to store the closure. – Sweeper Feb 13 '23 at 01:31
  • yes, i was looking some thing like those exactly, thanks –  Feb 13 '23 at 02:16
  • You can create a class that wraps a closure, with an `@objc func call()` method which invokes the closure. That way all your call sites just use regular Swift closures, but you can still call APIs that follow the target/action pattern – Alexander Feb 13 '23 at 03:09
  • `NSMenuItem` is subclass of `NSObject` so you will need to accept it. Alternatively you can look for 3rd party libraries that wraps Objective-C and have plain swift interfaces. – Cy-4AH Feb 13 '23 at 11:22

0 Answers0