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
Argument of '#selector' does not refer to an '@objc' method, property, or initializer
提问by MJQZ1347
I sublcassed in Swift 3 a UIButton
subclass 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 @objc
and there's no need for the self
reference 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 private
if 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 @objc
keyword in the front the method that is perfect, but I still got this error.
Finally, I found out the solution as follows
@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//)
}