Swift 3:为什么符号_是在发送者之前添加的动作参数?

我的Xcode最近已经更新到Xcode 8与Swift 3.我注意到,当附加动作ViewController函数生成在这种风格:

@IBAction func methodName(_ sender: UIButton) { } 

我不明白在那里有什么目的。 任何人都可以解释为什么在那里? 在以前的Swift 2.2中,它不在那里。

另一个问题是我以前通过观看教程完成的项目已经迁移到了Swift 3,并且有一种方法如下所示:

 func toggleButtons(toggle: Bool) { yesButton.isUserInteractionEnabled = toggle noButton.isUserInteractionEnabled = toggle } 

我正在像这样调用这个方法: toggleButtons(false)仍然没有传递参数名称。 现在,migrator如下所示更改了它,但是稍后在代码中调用方法时没有任何更改。

 func toggleButtons(_ toggle: Bool) { yesButton.isUserInteractionEnabled = toggle noButton.isUserInteractionEnabled = toggle } 

这与以前的情况不一样吗?

其他答案(其中一个已被删除)涵盖了_含义:当您调用方法时,它会消除关键字。

但是,您的问题是关于“附加操作ViewController”。

具有@IBAction属性的方法可以连接到故事板(或xib)中的控件。 这意味着方法的名称将作为string存储在故事板中,并且将使用Objective-C消息发送系统来调用。 所以确切的名称,以及如何将名称转换为Objective-C,在这里非常重要。

如果声明方法func methodName(sender: UIButton) ,那么它的Objective-C名称是methodNameWithSender:

如果你声明方法func methodName(_ sender: UIButton) ,那么它的Objective-C名称是methodName:

iOS和macOS都有一个叫做“响应者链”的东西,它可以让系统search一个可以处理动作的对象(一个“响应者”)。 您可以将故事板中的控件连接到First Responder(位于文档大纲的顶部),让系统执行此操作。 大多数情况下,您可以使用macOS中的菜单项执行此操作,但还有其他用途。

无论如何,有一些标准的行动,如cut:copy: paste: 。 例如,您可以将“剪切”菜单项的操作设置为“发送cut:到第一个响应者”。 如果你想在你的视图控制器中实现cut:方法,那么它的名字(当被转换为Objective-C时)被精确地cut:是非常重要的,而不是cutWithSender: 如果命名为cut: cutWithSender:系统会在search响应者链时find它,但是如果它被命名为cutWithSender:系统将不会find它,并且您会疑惑为什么菜单项不起作用。

Xcode知道这一点,所以它总是创buildforms为@IBAction func action(_ sender: UIButton)动作方法,从参数中省略关键字,以防执行需要通过search响应者链来查找的动作。

在Swift 3中,每个方法的参数默认都有一个关键字,包括第一个参数。 回到Swift 2,第一个参数默认没有关键字,所以第一个参数上的_是Swift 2中的冗余(并且会生成编译器警告)。 这就是为什么Xcode 8(Swift 3)放入_但Xcode 7(Swift 2.2)没有。

这也是为什么你的toggleButtons例子在Xcode 7中工作。

这意味着您在调用方法时不必命名该参数。

 obj.methodName(button) // no need for obj.methodName(sender: button) 

在之前的Swift版本中,这是方法调用中第一个参数的特殊默认行为,但是在统一的Swift3中。 现在所有参数都需要名称,除非您select(使用_ )。