ios “#selector”的参数不引用“@objc”方法、属性或初始值设定项

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41511973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 11:01:17  来源:igfitidea点击:

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

iosobjective-cswiftcocoa-touch

提问by MJQZ1347

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

我在 Swift 3 中继承了一个UIButton用 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

    }
}

采纳答案by cjrieck

All you have to do is mark the func as @objcand there's no need for the selfreference or the parenthesis

您所要做的就是将 func 标记为,@objc并且不需要self引用或括号

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 privateif you want

private如果你愿意,你甚至可以做到

回答by matt

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

问题是在#selector(self.action())self.action()是一个方法调用。您不想调用该方法;你想命名方法。#selector(action)而是说:去掉括号,而且不需要self.

回答by Victor John

Adding @objckeyword 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

@objc在前面添加关键字是完美的方法,但我仍然出现此错误。最后,我找到了解决方案如下 在此处输入图片说明

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.

如上图所示,方法后面有一对多余的括号。我应该做的是删除它并且它运行良好。

回答by dfd

Added from comments on another answer: func action()is not just a poor choice for a function name and action, it fails to build. (You can use it as an input function parameter though, which I do for clarity when passing in target/action to an init() that sets these things.) I'm replacing this with MyAction()for clarity.

从另一个答案的评论中添加:func action()不仅是函数名称和动作的糟糕选择,而且无法构建。(不过,您可以将它用作输入函数参数,为了清楚起见,在将目标/操作传递给设置这些内容的 init() 时我会这样做。为了清楚起见,我将其替换为MyAction()



Try this:

尝试这个:

self.addTarget(self, action: #selector(MyAction), for: .touchUpInside)

The said, a much better design is to move the MyAction() function to the button superview, as that makes things more aligned with basic MVC design:

据说,更好的设计是将 MyAction() 函数移动到按钮超级视图,因为这使事情更符合基本的 MVC 设计:

Superview:

超级视图:

let myButton = ActionButton()
// include other button setup here
myButton.addTarget(self, action: #selector(MyAction), for: .touchUpInside

func action(_ sender: ActionButton) {
    // code against button tap here
}

Alternative coding for this, keeping the "action()" method in the view controller but moving onlythe "addTarget" into the button:

对此的替代编码,将“action()”方法保留在视图控制器中,但将“addTarget”移动到按钮中:

self.addTarget(superview?, action(superview?.MyAction), for: .touchUpInside)

Why am I asking you to consider moving the "MyAction()" method to the superview? Twofold:

为什么我要你考虑将“MyAction()”方法移到父视图?双重:

  • It controls not only the button, but all other subviews in it's view and they commonly interact with each other via the view controller.
  • It makes the button much more reusable in other scenarios.
  • 它不仅控制按钮,还控制其视图中的所有其他子视图,它们通常通过视图控制器相互交互。
  • 它使按钮在其他情况下更具可重用性。

回答by Bawpotter

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

与其说,不如self.action()ActionButton.action()

回答by Eugene Temlock

If you don't mind adding an extra function, you could nest the function.

如果您不介意添加额外的功能,您可以嵌套该功能。

self.addTarget(self, action: myAction, for: UIControlledEvent)

myAction(){
    @obj.methodYouWantToCall(//parameters//)
}