首页 > 解决方案 > Swift 3.2 中的 UIControl addTarget(_:action:for:) 方法

问题描述

我有一个类,我们称它为 ClassA,使用以下 addTarget 调用。

awesomeBtn.addTarget(nil, action: #selector(awesomeMethod), for: .touchUpInside)

当方法 awesomeMethod 位于 ClassA 中时(即与 addTarget 调用相同的类),编译器接受上述行。

但是,如果 awesomeMethod 不在 ClassA 中,假设它在 ClassB 中,那么编译器会抱怨,我不得不在操作中指定类名。

awesomeBtn.addTarget(nil, action: #selector(ClassB.awesomeMethod), for: .touchUpInside)

在以前的 Swift 版本中(不确定是哪个版本),我可以简单地编写以下代码,而不管哪个类包含该方法。

awesomeBtn.addTarget(nil, action:("awesomeMethod"), forControlEvents:.touchUpInside)

想了解这是为什么,或者我是否做错了什么,谢谢。

标签: swiftaddtarget

解决方案


是的,他们将它从String如果您输入错误的方法名称只是一个运行时错误更改为#selector强制对该方法进行编译时检查。他们只是想早点发现你的错误。

但是,如果 awesomeMethod 不在 ClassA 中,假设它在 ClassB 中,那么编译器会抱怨,我不得不在操作中指定类名。

不,您可以指定一个@objc protocol实现该方法的方法:

@objc protocol AwesomeProtocol {
    func awesomeMethod()
}

然后,即使您的类没有实现该方法,您也可以指定:

awesomeBtn.addTarget(nil, action: #selector(AwesomeProtocol.awesomeMethod), for: .touchUpInside)

注意:似乎没有人需要采用该协议。该按钮向上搜索响应者链并使用它找到的第一个匹配方法。尽管如此,您应该在任何实现的类中采用该协议,awesomeMethod以便 Swift 可以在编译时检测方法签名中的错误。


推荐阅读