Swift3.0 - 黑魔法swizzle

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

  • 舉個例子理解一下

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

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

// 定義要交換的函數
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)
    // 看似好像調用了自己構成死循環,但是 我們其實已經將兩個方法名的實現進行了調換 所以 其實我們調用的是 方法sendAction:to:forEvent 的實現 這樣就可以在不破環原先方法結構的基礎上進行交換實現
    swizzle_sendAction(action: action, to: to, forEvent: forEvent)
}
}

使用

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

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

運行結果:

1
你好
2
你好
3
你好
4

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容