Selector 源自 Objective-C,例如 SEL 类型,以及 @selector() 方法选择器。
let btn = UIButton.init(type:.custom) btn.frame = CGRect.init(x: 40, y: 50, width: 40, height: 40); btn.backgroundColor = UIColor.red self.view.addSubview(btn) btn.addTarget(self, action:Selector("leftAction"), for: .touchUpInside)复制代码
并定义方法
func leftAction() { }复制代码
出现警告:No method declared with Objective-C selector 'leftAction',此时运行会崩溃。
这里是提示我们没有方法声明的Objective-C选择器
修改leftAction
方法,添加@objc
@objc func leftAction() { }复制代码
又出现警告:Use '#selector' instead of explicitly constructing a 'Selector' 点击fix警告消除,运行无误
btn.addTarget(self, action:#selector(HomeVC.leftAction), for: .touchUpInside)复制代码
这里添加HomeVC
类名引用是为了强声明是当前类的方法,若当前作用域构造 Selector 的方法名唯一时,可以省略作用域,直接使用方法名。
然后我们试一下同名方法,传参不同的情况
定义方法
@objc func leftAction(str:String) -> String { return "123"; }复制代码
编译报错,提示我们当前类不能使用leftAction这个方法
去掉作用域编译,报错如下然后我们将按钮的方法名修改为leftAction(btn:)
btn.addTarget(self, action:#selector(HomeVC.leftAction(btn:)), for: .touchUpInside)复制代码
程序可以正常运行,但是使用leftAction方法会报错。
原来还是参数不同的同名方法使用会有争议 处理方法:使用强制类型转换let methodA = #selector(leftAction as () -> ())let methodB = #selector(leftAction(btn:) as (UIButton) ->String)复制代码
然后添加方法,
btn.addTarget(self, action:methodA, for: .touchUpInside);复制代码
使用调用标准库中的私有方法时,只能通过字符串Seletcor("")
swift3.0之前继承方法可以用Selector("")
来构造。swift4.0之后只能通过#selector()
。
配合 Swift 的 Extension,可以使用其管理当前控制器的所有 Selector:
fileprivate extension Selector{ static let leftBtnClick = #selector(HomeVC.leftAction(btn:)) }复制代码
调用leftBtnClick
btn.addTarget(self, action:.leftBtnClick, for: .touchUpInside);复制代码