Swift4.0中Runtime method_exchangeImplementations的使用和initialize()方法的替代

在swift4.0中
load()方法已經失效
initialize()也失效
一時間我一度不知道怎麼用運行時的method_exchangeImplementations方法,後來在網上查看總結出來下面將代碼貼出來

extension UIViewController {
public class func initializeMethod(){
    let originalSelector = #selector(UIViewController.viewDidAppear(_:))
    let swizzledSelector = #selector(UIViewController.myMethod(animated:))

    let originalMethod = class_getInstanceMethod(self, originalSelector)
    let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)


    //在進行 Swizzling 的時候,需要用 class_addMethod 先進行判斷一下原有類中是否有要替換方法的實現
    let didAddMethod: Bool = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod!), method_getTypeEncoding(swizzledMethod!))
    //如果 class_addMethod 返回 yes,說明當前類中沒有要替換方法的實現,所以需要在父類中查找,這時候就用到 method_getImplemetation 去獲取 class_getInstanceMethod 裏面的方法實現,然後再進行 class_replaceMethod 來實現 Swizzing

    if didAddMethod {
        class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod!), method_getTypeEncoding(originalMethod!))
    } else {
        method_exchangeImplementations(originalMethod!, swizzledMethod!)
    }

    }

    @objc func myMethod(animated: Bool) {
        self.myMethod(animated: animated)
        print("替換了")

    }
}

在AppDelegate的
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:方法中添加如下代碼

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
      UIViewController.initializeMethod()
        return true
    }

下面看一下調用和打印結果
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章