Argument of '#selector' does not refer to an '@objc' method, property, or initializer

60,396

Solution 1

All you have to do is mark the func as @objc and there's no need for the self reference or the parenthesis

class ActionButton: JTImageButton {

    @objc func btnAction() {

    }

    func configure() {
        // ...
        self.addTarget(self, action: #selector(btnAction), for: .touchUpInside)
        // error: 
        // Argument of '#selector' does not refer to an '@objc' method, property, or initializer

    }
}

You can even make it private if you want

Solution 2

The problem is that in #selector(self.action()), self.action() is a method call. You don't want to call the method; you want to name the method. Say #selector(action) instead: lose the parentheses, plus there's no need for the self.

Solution 3

Adding @objc keyword in the front the method that is perfect, but I still got this error. Finally, I found out the solution as follows enter image description here

There is a pair of superfluous parentheses behind the method as picture shown above. What I should do is that remove it and it worked well.

Solution 4

Instead of saying self.action(), use ActionButton.action().

Share:
60,396
MJQZ1347
Author by

MJQZ1347

Updated on December 16, 2020

Comments

  • MJQZ1347
    MJQZ1347 over 3 years

    I sublcassed in Swift 3 a UIButton subclass that is written in Objective-C.

    When I try to add a target, it fails with an error code:

    class ActionButton: JTImageButton {
    
        func action() {
    
        }
    
        func configure()) {
            // ...
            self.addTarget(self, action: #selector(self.action()), for: .touchUpInside)
            // error: 
            // Argument of '#selector' does not refer to an '@objc' method, property, or initializer
    
        }
    }
    
  • MJQZ1347
    MJQZ1347 over 7 years
    Thanks, but it says Ambiguous use of 'action' when I implemented your approach? Edit: Renaming action() to action2() helped.
  • Martin R
    Martin R over 7 years
    In addition, it conflicts with the action(for:, forKey:) method of UIView. #selector(action) will give an "ambiguous use" and your Q&A stackoverflow.com/questions/35658334/… applies.
  • cjrieck
    cjrieck over 7 years
    Weird. I renamed the method to be btnAction and it doesn't give me that error. Maybe something to do with the function name, action? I've updated my answer to show what I mean
  • Ashok R
    Ashok R over 7 years
    so func action() { } has to be repalced with some other name as @matt said otherwise you will end up with Ambiguous use of action() error.
  • Martin R
    Martin R over 7 years
    You don't need the @objc because the class already inherits from NSObject.
  • cjrieck
    cjrieck over 7 years
    True. Since it's a public method on an NSObject there's no need for the @objc. If the func were to be made private it would be needed
  • Admin
    Admin over 7 years
    Agreed. I'll point that out in my answer. I was answering the intent of the question, not the technicals. I shouldn't do that!
  • Papershine
    Papershine over 6 years
    This doesn't answer the question's needs. Also, please don't repost answers.
  • Johnny
    Johnny over 6 years
    This is the answer I came across, and someone may encounter too. And I solved it by removing the parenthesis. Why you downvoted my answer? It's REAL answer! @paper1111
  • Krunal Nagvadia
    Krunal Nagvadia over 4 years
    What if function with more than one Argument?
  • matt
    matt over 4 years
    What if it does?
  • Let.Simoo
    Let.Simoo over 3 years
    What if the named func has more than one Argument... how and where to fill those Arguments??
  • matt
    matt over 3 years
    @Let.Simoo There are no arguments in a #selector expression. You are describing the method, not calling it.