理解Swift 2.2 Selector语法 – #selector()

我将我的项目语法切换到Swift 2.2(xCode帮助我自动执行); 不过,我不明白新的#selector()语法。

举个例子:

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

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

_:是什么意思? 你可以添加其他variables到这个select器? 说, #MyVC.timerCalled(_:whateverVar)

不同于早期版本的Swift的基于string的实现,在这个语法中有什么不同的一般信息非常感谢。

括号中的位是用于标识所需select器的参数列表的机制。

我build议你看一下Swift Evolution的通用命名提议。 它涵盖了许多function只有参数标签不同而且需要参考的function。 该文件的例子是:

 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 

实现的解决scheme是添加参数标签,没有任何types的信息生成函数值的代码来消除你想要的:

 let fn = someView.insertSubview(_:at:) let fn1 = someView.insertSubview(_:aboveSubview:) 

看看标签是如何添加到父亲的?

这个提议在最直接适用于你的问题的那个方面起到了作用:

引用方法的Objective-Cselect器

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

Swift 2.2已经弃用了string化select器:在swift 2.0中,我们使用将select器写成string,即"buttonClicked" 。 这种方法的缺点是在编译时编译器不能检查方法是否真的存在(即使你拼错了)。

EX:1

 func buttonClicked(){ } 

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

EX:2

 func buttonClicked(stringValue : String){ } 

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

EX:3

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

所以在新方法中使用参数的上述方法可以被称为#selector(buttonClicked(_:indexValue:))

请考虑下面的代码,使用#select器在swift 3中将button添加到button

 button.addTarget(self, action: #selector(self.buttonAction(sender:)), for: UIControlEvents.touchUpInside) func buttonAction(sender:UIButton!){ } 

在迁移到swift 3时,这个语法适用于我

这就是Swift方法签名在文档中的performance方式,现在它开始被用在新的语言特性中,例如#selector()语法,用它们的参数列表来表示方法。

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

因此,例如, MyVC.timerCalled(_:))表示MyVCtypes上的一个未命名参数的方法,可以这样声明:

 func timerCalled(timer: NSTimer) { ... } 

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

如果它在#selector()声明的相同范围内,types(在你的例子中是MyVC )也可以被省略。

一个更复杂的例子可能是这样的:

 let sel = #selector(aMethodWithSeveralParameters(_:secondParam:thirdParam:)) ... func aMethodWithSeveralParameters(firstParam: Int, secondParam: Int, thirdParam: Int) { ... }