Xcode 7.3 / Swift 2: "No method declared with Objective-C selector" 警告

47

我已经使用选择器一段时间了,即使迁移到Swift后也可以毫无问题地使用它们。这就是我在Swift 2上使用时没有问题的方式,直到我将Xcode更新到版本7.3:

enter image description here

正如您所看到的,我在NSTimer中使用选择器。

这是被调用的动作:

 func Start () {

 }

你可以看到,Xcode 7.3 现在会给出一个警告 "没有使用 Objective-C 选择器声明的方法"。点击警告后,Xcode 提供了一个快速修复代码的选项,添加了 "Selector",但我仍然得到相同的警告:输入图像描述

4个回答

92

自从Swift 2.2 / Xcode 7.3,使用选择器的新方法:

Selector("funcName")已更改为#selector(ClassName.funcName)

请参阅https://github.com/apple/swift-evolution/blob/master/proposals/0022-objc-selectors.md

tl; dr;

Selector("Start")替换为#selector(YOUR_CLASS.Start)

其中YOUR_CLASS =上下文中目标类。

如果您不想手动操作,Xcode提供默认的易于修正工具,当您遇到以下情况时,请点击黄色三角形(有时需要多次点击)。

enter image description here

它会给您建议:

在此输入图像描述

如果您选择该建议,它将自动更新选择器:

在此输入图像描述

2
这样做好多了,不再因为打错字而崩溃。 - crashoverride777
1
不确定你的意思?在Swift 2.2之前,选择器被定义为字符串类型,因此如果您打错了,编译器不会发出警告。 - crashoverride777
1
值得注意的是,由于这个问题可能经常被链接到,方法名通常以小写字母开头,因此 func StartYOUR_CLASS.Start 应该改为 func startYOUR_CLASS.start - Aaron Brager
1
@crashoverride777:如果同一个方法在两个不同的类中使用,我需要做什么? - Donal
1
这个方法能否传递参数? - Dave G
显示剩余3条评论

4

以下两个语句都能正常工作。通常使用第一个语句。但是,当选择器方法在不同的视图控制器中时,编译器会出现“没有声明Objective-C选择器'buttonHandler'”的警告。

第二个语句不会产生这个警告。

button.addTarget(parentViewController, action: Selector("buttonHandler:"), forControlEvents: .TouchUpInside)

button.addTarget(parentViewController, action: #selector(MainViewController.buttonHandler), forControlEvents: .TouchUpInside)

在目标视图控制器(MainViewController)中,您可以定义模块:
func buttonHandler(sender:UIButton!) {
    print ("Pressed")
}

虽然它会给出一个警告,但它是可用的。刚在Apple Swift版本2.2上测试过。请注意必须要有冒号“:”。 - Vincent

2

在Swift 4中,我需要在函数前添加@objc以消除警告。

这是我使用NSTimer调用函数的方式:

 Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.intro), userInfo: nil, repeats: false)

这是func的声明方式:

     @objc func intro () {

          // do your stuff here         

     }

我已经按照Xcode的要求更新了设置:

enter image description here

现在没有警告了,一切似乎都正常工作。

0

我有一些自己的发现来支持Vincent所说的(太长了不能直接评论)

这不一定是在另一个视图控制器中,而是在一个不同的文件中,以下格式将无法使用:

button.addTarget(parentViewController, action: Selector("buttonHandler:"), forControlEvents: .TouchUpInside)

例如,如果您在单独的文件中使用扩展,即使针对相同的视图控制器,这种格式Selector("buttonHandler:")也无法工作。

此外,当选择器同一文件和VC中时,Xcode的快速修复功能会提示您让选择器包括构造函数,因此它看起来像这样:

#selector(MainViewController.buttonHandler(_:))

然而,这种格式仅在选择器位于相同的VC +文件中时起作用。如果它位于单独的文件中但是在相同的VC中,则该推荐方法将无法工作,您需要使用不带构造函数的方法。

#selector(MainViewController.buttonHandler)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接