I've been using selectors for a while, and even after migrating to Swift I was able to use them without issues. That's how I was using on Swift 2 without issues until I updated Xcode to version 7.3:
我使用选择器已经有一段时间了,甚至在迁移到Swift之后,我也可以毫无问题地使用它们。这就是我使用Swift 2的方式,直到我将Xcode更新为7.3版:
As use can see I use selectors with NSTimer.
可以看到,我使用了选择器和NSTimer。
This is the action that is called:
这就是所谓的行动:
func Start () {
}
As you can see Xcode 7.3 now gives a warning "No method declared with Objective-C selector". By clicking on the warning, Xcode offers a quick fix to the code by adding "Selector", but then I still get the same warning:
如您所见,Xcode 7.3现在给出了一个警告“没有使用Objective-C选择器声明的方法”。通过单击警告,Xcode通过添加“Selector”对代码进行了快速修复,但我仍然得到相同的警告:
4 个解决方案
#1
79
Since Swift 2.2 / Xcode 7.3 there is a new way to use a selector: Selector("funcName")
was changed to #selector(ClassName.funcName)
由于Swift 2.2 / Xcode 7.3,有一种新的方法可以使用selector: selector(“funcName”)被更改为#selector(ClassName.funcName)
Have a look at https://github.com/apple/swift-evolution/blob/master/proposals/0022-objc-selectors.md ,
看看https://github.com/apple/swift-演进/ blob/master/sals/0022 - objectors.md,
tl;dr;
tl,博士;
Replace Selector("Start")
with #selector(YOUR_CLASS.Start)
替代选择器(“开始”)#选择器(YOUR_CLASS.Start)
where YOUR_CLASS = class of target in given context.
其中YOUR_CLASS =目标的类。
If you don't want to do it manually, Xcode provides easy fix itself by default, when you have the following situation, tap on the Yellow triangles ( sometimes required to tap/click multiple times ),
如果您不想手工操作,Xcode默认提供了简单的修复,当您有以下情况时,点击黄色三角形(有时需要多次点击),
它会给你建议:
And if you select that suggestion, it will automatically update the selector:
如果你选择那个建议,它会自动更新选择器:
#2
3
Both following statements work perfectly. The upper one is mostly used. However when the selector method is in a different ViewController the compiler warning "No method declared with Objective-C selector 'buttonHandler'" may occur.
以下两种说法都很有效。上面的部分大部分是用的。但是,当选择器方法位于不同的ViewController中时,编译器会发出警告,“不会出现使用Objective-C选择器'buttonHandler'声明的方法”。
The second listed statement does not give this warning.
第二个列出的语句没有给出这个警告。
button.addTarget(parentViewController, action: Selector("buttonHandler:"), forControlEvents: .TouchUpInside)
button.addTarget(parentViewController, action: #selector(MainViewController.buttonHandler), forControlEvents: .TouchUpInside)
In the target view controller (MainViewController) you can define the module:
在目标视图控制器(MainViewController)中,您可以定义模块:
func buttonHandler(sender:UIButton!) {
print ("Pressed")
}
#3
1
On Swift 4 I had to add @objc before the func to get rid of the warnings.
在Swift 4上,我必须在func之前添加@objc以消除警告。
This is how I call the func with NSTimer:
我用NSTimer这样称呼func:
Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.intro), userInfo: nil, repeats: false)
This is how the func is declared:
以下是基金会的声明:
@objc func intro () {
// do your stuff here
}
I also updated the setting as the Xcode requested:
我还按照Xcode的要求更新了设置:
No more warnings, everything seems to be working fine.
没有更多的警告,一切似乎都很顺利。
#4
0
Some findings of my own to support what Vincent said (too long to be a direct comment)
我自己的一些发现支持文森特所说的话(太长了不能直接评论)
It's not necessarily in a different view controller, but just a different file where the following format won't work:
它不一定是在不同的视图控制器中,而是在不同的文件中,以下格式不能工作:
button.addTarget(parentViewController, action: Selector("buttonHandler:"), forControlEvents: .TouchUpInside)
按钮。addTarget(parentViewController, action: Selector(“buttonHandler:”),forControlEvents: .TouchUpInside)
For instance, if you have an extension in a separate file, although for the same view controller, this format Selector("buttonHandler:")
won't work.
例如,如果在一个单独的文件中有一个扩展,尽管对于相同的视图控制器,这个格式选择器(“buttonHandler:”)不能工作。
Further, when the selector is in the same file and VC, Xcode's quick-fix prompts you to have the selector include the constructor, so it would look something like this:
此外,当选择器位于相同的文件和VC中时,Xcode的快速修复会提示您让选择器包含构造函数,所以它看起来是这样的:
#selector(MainViewController.buttonHandler(_:))
#选择器(MainViewController.buttonHandler(_)):
However this format only works when the selector is in the same VC + file, if it is in a separate file, but same VC, then that recommended method won't work, and you need to use the method without the constructor
但是,这种格式只在选择器位于相同的VC +文件中时才有效,如果选择器位于单独的文件中,但是在相同的VC中,那么推荐的方法将不起作用,您需要使用没有构造函数的方法
#selector(MainViewController.buttonHandler)
#选择器(MainViewController.buttonHandler)
#1
79
Since Swift 2.2 / Xcode 7.3 there is a new way to use a selector: Selector("funcName")
was changed to #selector(ClassName.funcName)
由于Swift 2.2 / Xcode 7.3,有一种新的方法可以使用selector: selector(“funcName”)被更改为#selector(ClassName.funcName)
Have a look at https://github.com/apple/swift-evolution/blob/master/proposals/0022-objc-selectors.md ,
看看https://github.com/apple/swift-演进/ blob/master/sals/0022 - objectors.md,
tl;dr;
tl,博士;
Replace Selector("Start")
with #selector(YOUR_CLASS.Start)
替代选择器(“开始”)#选择器(YOUR_CLASS.Start)
where YOUR_CLASS = class of target in given context.
其中YOUR_CLASS =目标的类。
If you don't want to do it manually, Xcode provides easy fix itself by default, when you have the following situation, tap on the Yellow triangles ( sometimes required to tap/click multiple times ),
如果您不想手工操作,Xcode默认提供了简单的修复,当您有以下情况时,点击黄色三角形(有时需要多次点击),
它会给你建议:
And if you select that suggestion, it will automatically update the selector:
如果你选择那个建议,它会自动更新选择器:
#2
3
Both following statements work perfectly. The upper one is mostly used. However when the selector method is in a different ViewController the compiler warning "No method declared with Objective-C selector 'buttonHandler'" may occur.
以下两种说法都很有效。上面的部分大部分是用的。但是,当选择器方法位于不同的ViewController中时,编译器会发出警告,“不会出现使用Objective-C选择器'buttonHandler'声明的方法”。
The second listed statement does not give this warning.
第二个列出的语句没有给出这个警告。
button.addTarget(parentViewController, action: Selector("buttonHandler:"), forControlEvents: .TouchUpInside)
button.addTarget(parentViewController, action: #selector(MainViewController.buttonHandler), forControlEvents: .TouchUpInside)
In the target view controller (MainViewController) you can define the module:
在目标视图控制器(MainViewController)中,您可以定义模块:
func buttonHandler(sender:UIButton!) {
print ("Pressed")
}
#3
1
On Swift 4 I had to add @objc before the func to get rid of the warnings.
在Swift 4上,我必须在func之前添加@objc以消除警告。
This is how I call the func with NSTimer:
我用NSTimer这样称呼func:
Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.intro), userInfo: nil, repeats: false)
This is how the func is declared:
以下是基金会的声明:
@objc func intro () {
// do your stuff here
}
I also updated the setting as the Xcode requested:
我还按照Xcode的要求更新了设置:
No more warnings, everything seems to be working fine.
没有更多的警告,一切似乎都很顺利。
#4
0
Some findings of my own to support what Vincent said (too long to be a direct comment)
我自己的一些发现支持文森特所说的话(太长了不能直接评论)
It's not necessarily in a different view controller, but just a different file where the following format won't work:
它不一定是在不同的视图控制器中,而是在不同的文件中,以下格式不能工作:
button.addTarget(parentViewController, action: Selector("buttonHandler:"), forControlEvents: .TouchUpInside)
按钮。addTarget(parentViewController, action: Selector(“buttonHandler:”),forControlEvents: .TouchUpInside)
For instance, if you have an extension in a separate file, although for the same view controller, this format Selector("buttonHandler:")
won't work.
例如,如果在一个单独的文件中有一个扩展,尽管对于相同的视图控制器,这个格式选择器(“buttonHandler:”)不能工作。
Further, when the selector is in the same file and VC, Xcode's quick-fix prompts you to have the selector include the constructor, so it would look something like this:
此外,当选择器位于相同的文件和VC中时,Xcode的快速修复会提示您让选择器包含构造函数,所以它看起来是这样的:
#selector(MainViewController.buttonHandler(_:))
#选择器(MainViewController.buttonHandler(_)):
However this format only works when the selector is in the same VC + file, if it is in a separate file, but same VC, then that recommended method won't work, and you need to use the method without the constructor
但是,这种格式只在选择器位于相同的VC +文件中时才有效,如果选择器位于单独的文件中,但是在相同的VC中,那么推荐的方法将不起作用,您需要使用没有构造函数的方法
#selector(MainViewController.buttonHandler)
#选择器(MainViewController.buttonHandler)