Swift3.0 - 黑魔法swizzle

Swift3.0 - 真的很簡單
Swift3.0 - 數(shù)據(jù)類型
Swift3.0 - Array
Swift3.0 - 字典
Swift3.0 - 可選值
Swift3.0 - 集合
Swift3.0 - 流控制
Swift3.0 - 對象和類
Swift3.0 - 屬性
Swift3.0 - 函數(shù)和閉包
Swift3.0 - 初始化和釋放
Swift3.0 - 協(xié)議protocol
Swift3.0 - 類和結構體的區(qū)別
Swift3.0 - 枚舉
Swift3.0 - 擴展
Swift3.0 - 下標
Swift3.0 - 泛型
Swift3.0 - 異常錯誤
Swift3.0 - 斷言
Swift3.0 - 自動引用計數(shù)(strong,weak,unowned)
Swift3.0 - 檢測API
Swift3.0 - 對象的標識
Swift3.0 - 注釋
Swift3.0 - 元類型
Swift3.0 - 空間命名
Swift3.0 - 對象判等
Swift3.0 - 探究Self的用途
Swift3.0 - 類簇
Swift3.0 - 動態(tài)調用對象(實例)方法
Swift3.0 - 文本輸出
Swift3.0 - 黑魔法swizzle
Swift3.0 - 鏡像
Swift3.0 - 遇到的坑

  • 舉個例子理解一下

如果你想統(tǒng)計App中所有頁面的點擊事件,最簡單快捷的方式是什么?

  extension UIButton{
   class func swip(){
    // 創(chuàng)建一個結構體,寫個靜態(tài)變量
    struct T{
        static let x:Bool = {
            let cls: AnyClass = UIButton.self
            // 創(chuàng)建消息對象
            let originalSelector = #selector(UIButton.sendAction(_:to:for:))
            let swizzleSelector = #selector(UIButton.swizzle_sendAction(action:to:forEvent:))
            // 創(chuàng)建方法
            let ori_method = class_getInstanceMethod(cls, originalSelector)
            let swi_method = class_getInstanceMethod(cls, swizzleSelector)
            
            print(ori_method)
            print(swi_method)
            // 交換兩個方法的實現(xiàn)部分
            method_exchangeImplementations(ori_method,swi_method)
            print("執(zhí)行了............")
            return false
        }()
    }
    // 這里必須執(zhí)行一下,不然沒法創(chuàng)建靜態(tài)變量
    T.x
}

// 定義要交換的函數(shù)
public  func swizzle_sendAction(action: Selector,
                                to: AnyClass!,
                                forEvent: UIEvent!){
    // 定義一個累加器
    struct button_tap_count{
        static var count = 0
    }
    button_tap_count.count += 1
    print(button_tap_count.count)
    // 看似好像調用了自己構成死循環(huán),但是 我們其實已經(jīng)將兩個方法名的實現(xiàn)進行了調換 所以 其實我們調用的是 方法sendAction:to:forEvent 的實現(xiàn) 這樣就可以在不破環(huán)原先方法結構的基礎上進行交換實現(xiàn)
    swizzle_sendAction(action: action, to: to, forEvent: forEvent)
}
}

使用

class ViewController: UIViewController {
     @IBOutlet weak var button: UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
         // 執(zhí)行一次交換方法
         UIButton.swip()
         button.addTarget(self, action: #selector(tap(button:)), for: .touchUpInside)
    }

    func tap(button:UIButton){
        print("你好")
    }
}

運行結果:

1
你好
2
你好
3
你好
4

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容