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(使用_
)。