理解Swift 2.2选择器语法-#选择器()

理解Swift 2.2选择器语法-#选择器(),swift,swift2,selector,Swift,Swift2,Selector,我正在将我的项目的语法转换为Swift 2.2(xCode帮助我自动完成);但是,我不理解新的#selector()语法 例如: timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(MyVC.timerCalled(_:)), //new selector syntax! userInfo: nil, repeats: tr

我正在将我的项目的语法转换为Swift 2.2(xCode帮助我自动完成);但是,我不理解新的
#selector()
语法

例如:

timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, 
             selector: #selector(MyVC.timerCalled(_:)), //new selector syntax!
             userInfo: nil, repeats: true)
这有选择器
#选择器(MyVC.timerCalled(:)

\:
表示什么?您可以将其他变量添加到此选择器中吗?比如说,
#MyVC.timerCalled(u:whateverVar)


非常感谢您提供有关此语法与早期版本Swift基于字符串的实现不同之处的一般信息。

这是Swift方法签名在文档中的表示方式,现在它开始用于新的语言功能,如
#selector()
通过参数列表表示方法的语法

每个冒号(
)表示一个方法参数。对于命名参数,冒号前面是外部参数名称;对于未命名的参数,使用下划线(

因此,例如,
MyVC.timerCalled(:)
表示
MyVC
类型上有一个未命名参数的方法,该参数可以如下声明:

func timerCalled(timer: NSTimer) { ... }
let sel = #selector(aMethodWithSeveralParameters(_:secondParam:thirdParam:))

...

func aMethodWithSeveralParameters(firstParam: Int, secondParam: Int, thirdParam: Int) { ... }
(请注意,
timer
是内部参数名,因为默认情况下,方法的第一个参数未命名)

如果类型(
MyVC
在您的示例中)在
#selector()
声明的相同范围内,也可以省略它

更复杂的示例可能如下所示:

func timerCalled(timer: NSTimer) { ... }
let sel = #selector(aMethodWithSeveralParameters(_:secondParam:thirdParam:))

...

func aMethodWithSeveralParameters(firstParam: Int, secondParam: Int, thirdParam: Int) { ... }

括号中的位是一种机制,用于标识所需选择器的参数列表

我建议你看看Swift Evolution的提案。它涵盖了许多函数仅因参数标签不同而需要引用它们的情况。该文件中的示例如下:

extension UIView {
  func insertSubview(view: UIView, at index: Int)
  func insertSubview(view: UIView, aboveSubview siblingSubview: UIView)
  func insertSubview(view: UIView, belowSubview siblingSubview: UIView)
}
如果要为其中一个函数获取函数值,则结果不明确:

let fn = someView.insertSubview // ambiguous: could be any of the three methods
实现的解决方案是在生成函数值的代码中添加参数标签,而不添加任何类型信息,以消除您想要的歧义:

let fn = someView.insertSubview(_:at:)
let fn1 = someView.insertSubview(_:aboveSubview:)
查看如何将标签添加到参数中

该提案在最直接适用于您的问题的提案中发挥了作用:


在这种特殊情况下,您要引用的选择器是
timerCalled:
,它是一个没有标签的参数的函数。因此(389;:)。下划线表示未指定标签和冒号。

Swift 2.2已弃用字符串化选择器:在Swift 2.0中,我们使用将选择器写入字符串,即
“buttonClicked”
。这种方法的缺点是编译器无法在编译时检查该方法是否确实存在(即使您拼写错误)

EX:1

func buttonClicked(){
}
因此,新方法中的上述方法可以称为
#选择器(buttonClicked)

EX:2

func buttonClicked(stringValue : String){
}
因此,新方法中的上述方法可以称为
#选择器(按钮点击(:)

EX:3

func buttonClicked(stringValue : String, indexValue : Int){
}

因此,在新方法中,上述带有参数的方法可以称为
#选择器(buttonClicked(u:indexValue:)

请考虑以下代码,以便使用#选择器将目标添加到swift 3中的按钮


在迁移到swift 3时,这种语法对我很有用。

我想我在这里解释得很好:@matt的回答更全面地阐述了语法,包括一个关于处理重载方法的有用讨论。嘿,我刚刚读了这个问题。你能简单地向我解释一下为什么编译器在转换成swift 2.2时会将上面的示例修改为#选择器(YourClass.buttonClicked),而不是仅仅修改为#选择器(buttonClicked)。两者之间有区别吗?感谢you@crashoverride777我想你的问题在这里解释得很清楚。。我认为您总是需要在方法声明前面加上@objc