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

Ant*_*ito 36 selector swift swift2

我正在将我的项目语法切换到Swift 2.2(xCode帮助我自动完成); 但是,我不明白新的#selector()语法.

举个例子:

timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, 
             selector: #selector(MyVC.timerCalled(_:)), //new selector syntax!
             userInfo: nil, repeats: true)
Run Code Online (Sandbox Code Playgroud)

这有选择器 #selector(MyVC.timerCalled(_:))

_:意味着什么?你能在这个选择器中添加其他变量吗?说,#MyVC.timerCalled(_:whateverVar).

关于这种语法的不同之处的一般信息与早期版本的Swift中基于字符串的实现相反,我们非常感激.

Sco*_*son 31

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

我建议你看一下Swift Evolution 的Generalized Naming提议.它涵盖了一些情况,其中有许多功能仅由参数标签不同而需要引用它们.该文件的例子是:

extension UIView {
  func insertSubview(view: UIView, at index: Int)
  func insertSubview(view: UIView, aboveSubview siblingSubview: UIView)
  func insertSubview(view: UIView, belowSubview siblingSubview: UIView)
}
Run Code Online (Sandbox Code Playgroud)

如果你想获得其中一个的函数值,结果是不明确的:

let fn = someView.insertSubview // ambiguous: could be any of the three methods
Run Code Online (Sandbox Code Playgroud)

实现的解决方案是将参数标签添加到生成函数值的代码中,而不添加任何类型信息以消除您想要的歧义:

let fn = someView.insertSubview(_:at:)
let fn1 = someView.insertSubview(_:aboveSubview:)
Run Code Online (Sandbox Code Playgroud)

看看如何在parens中添加标签?

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

引用方法的Objective-C选择器

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


Dur*_*lli 19

Swift 2.2已弃用Stringified选择器:在swift 2.0中,我们使用将选择器编写为String ie "buttonClicked".这种方法的缺点是编译器无法在编译时检查方法是否确实存在(即使您拼错了它).

EX:1

func buttonClicked(){
}
Run Code Online (Sandbox Code Playgroud)

所以新方法中的上述方法可以称为 #selector(buttonClicked)

EX:2

func buttonClicked(stringValue : String){
}
Run Code Online (Sandbox Code Playgroud)

所以新方法中的上述方法可以称为 #selector(buttonClicked(_:))

EX:3

func buttonClicked(stringValue : String, indexValue : Int){
}
Run Code Online (Sandbox Code Playgroud)

因此,上述带有新方法参数的方法可以称为 #selector(buttonClicked(_:indexValue:))


Ank*_*kit 9

考虑下面的代码,使用#selector将目标添加到swift 3中的按钮

button.addTarget(self, action: #selector(self.buttonAction(sender:)),
                       for: UIControlEvents.touchUpInside)

 func buttonAction(sender:UIButton!){

 }
Run Code Online (Sandbox Code Playgroud)

迁移到swift 3时,此语法对我有用


Stu*_*art 8

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

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

例如,MyVC.timerCalled(_:))指示一个MyVC带有一个未命名参数的类型的方法,可以这样声明:

func timerCalled(timer: NSTimer) { ... }
Run Code Online (Sandbox Code Playgroud)

(注意,这timer内部参数名称,因为默认情况下,方法的第一个参数是未命名的)

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

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

let sel = #selector(aMethodWithSeveralParameters(_:secondParam:thirdParam:))

...

func aMethodWithSeveralParameters(firstParam: Int, secondParam: Int, thirdParam: Int) { ... }
Run Code Online (Sandbox Code Playgroud)