swift中 Selector的使用

7,389 阅读1分钟

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);