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

Mar*_*rat 5 xcode ios swift swift3

我的Xcode最近已经使用Swift 3更新为Xcode 8.我注意到,当以这种方式生成对ViewController函数的附加操作时:

@IBAction func methodName(_ sender: UIButton) {

}
Run Code Online (Sandbox Code Playgroud)

我不明白在_那里的目的是什么.任何人都可以解释它为什么存在吗?在之前的Swift 2.2中它并不存在.

另一个问题是,我通过观看教程完成的先前项目已迁移到Swift 3,并且有一种方法看起来像这样:

func toggleButtons(toggle: Bool) {
    yesButton.isUserInteractionEnabled = toggle
    noButton.isUserInteractionEnabled = toggle
}
Run Code Online (Sandbox Code Playgroud)

我这样调用这个方法:toggleButtons(false)仍然没有传递参数名称.现在,迁移器已经如下所示进行了更改,但是稍后在代码中调用方法时没有任何更改.

func toggleButtons(_ toggle: Bool) {
    yesButton.isUserInteractionEnabled = toggle
    noButton.isUserInteractionEnabled = toggle
}
Run Code Online (Sandbox Code Playgroud)

这是与前一案件不同的情况吗?

rob*_*off 9

其他答案(其中一个已删除)涵盖了_手段:它在您调用方法时删除了关键字.

但是,您的问题具体是"将操作附加到ViewController".

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

如果声明方法func methodName(sender: UIButton),则其Objective-C名称为methodNameWithSender:.

如果声明方法func methodName(_ sender: UIButton),则其Objective-C名称为methodName:.

iOS和macOS都有称为"响应者链"的东西,它允许系统搜索可以处理动作的对象("响应者").您可以连接控制在你的故事板第一响应者(在文档大纲的顶部),让系统做到这一点.最常见的是,您使用macOS中的菜单项执行此操作,但还有其他用途.

无论如何,有一些标准的动作,比如cut:,copy:和paste:.例如,您可以将"剪切"菜单项的操作设置为发送cut:给"第一响应者".如果要cut:在视图控制器中实现该方法,那么关键是它的名称(当转换为Objective-C时)是精确的cut:,而不是cutWithSender:.如果它的命名cut:,系统会搜索响应链时发现它,但如果它的命名cutWithSender:,系统将无法找到它,你会想知道为什么你的菜单项不起作用.

Xcode知道这一点,所以它总是创建表单的动作方法@IBAction func action(_ sender: UIButton),省略参数中的关键字,以防你实现需要通过搜索响应者链找到的动作.

在Swift 3中,方法的每个参数默认都有一个关键字,包括第一个参数.早在斯威夫特2,第一个参数并没有在默认情况下一个关键字,所以_第一个参数是斯威夫特2个冗余(并会生成一个编译器警告).这就是为什么Xcode 8(Swift 3)放入_但Xcode 7(Swift 2.2)没有.

这也是你的toggleButtons例子在Xcode 7中工作的原因.