swift中 Selector的使用

西門吹霧發表於2018-01-06

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這個方法

swift中 Selector的使用
去掉作用域編譯,報錯如下

swift中 Selector的使用

然後我們將按鈕的方法名修改為leftAction(btn:)

btn.addTarget(self, action:#selector(HomeVC.leftAction(btn:)), for: .touchUpInside)
複製程式碼

程式可以正常執行,但是使用leftAction方法會報錯。

swift中 Selector的使用
原來還是引數不同的同名方法使用會有爭議 處理方法:使用強制型別轉換

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);
複製程式碼

相關文章