日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于Swift4.0 Method Swizzling(iOS的hook机制)使用

發布時間:2025/7/25 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于Swift4.0 Method Swizzling(iOS的hook机制)使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

關于Method Swizzling 原理什么的有很多帖子講述的已經很清楚這里不再贅述,

這里僅僅處理Method Swizzling 在swift4.0中的使用方法

因為Swift本身對Runtime的支持并不是很到位,尤其是Method-Swizzling在OC中非常常用,但是到Swift后發現load方法不見了進而需要用initialize代替,甚至到了Swift4中直接取消了initialize方法。因此需要自己初始化

解決方案需要在appdelegate 添加這一行代碼
?UIViewController.initializeMethod()

/**需要在appdelegate 添加這一行代碼UIViewController.initializeMethod()*/

?

private let onceToken = "Method Swizzling"extension UIViewController {public class func initializeMethod() {// Make sure This isn't a subclass of UIViewController, So that It applies to all UIViewController childsif self != UIViewController.self {return}//DispatchQueue函數保證代碼只被執行一次,防止又被交換回去導致得不到想要的效果DispatchQueue.once(token: onceToken) {let originalSelector = #selector(UIViewController.viewWillAppear(_:))let swizzledSelector = #selector(UIViewController.swizzled_viewWillAppear(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 來實現 Swizzingif didAddMethod {class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod!), method_getTypeEncoding(originalMethod!))} else {method_exchangeImplementations(originalMethod!, swizzledMethod!)}let originalSelector1 = #selector(UIViewController.viewWillDisappear(_:))let swizzledSelector1 = #selector(UIViewController.swizzled_viewWillDisappear(animated:))let originalMethod1 = class_getInstanceMethod(self, originalSelector1)let swizzledMethod1 = class_getInstanceMethod(self, swizzledSelector1)//在進行 Swizzling 的時候,需要用 class_addMethod 先進行判斷一下原有類中是否有要替換方法的實現let didAddMethod1: Bool = class_addMethod(self, originalSelector1, method_getImplementation(swizzledMethod1!), method_getTypeEncoding(swizzledMethod1!))if didAddMethod1 {class_replaceMethod(self, swizzledSelector1, method_getImplementation(originalMethod1!), method_getTypeEncoding(originalMethod1!))} else {method_exchangeImplementations(originalMethod1!, swizzledMethod1!)}}}@objc func swizzled_viewWillAppear(animated: Bool) {//需要注入的代碼寫在此處self.swizzled_viewWillAppear(animated: animated)DDLOG(message: "\(NSStringFromClass(classForCoder))--Appear")}@objc func swizzled_viewWillDisappear(animated: Bool) {//需要注入的代碼寫在此處self.swizzled_viewWillDisappear(animated: animated)DDLOG(message: "\(NSStringFromClass(classForCoder))--Disappear")} }

由于swift 沒有DispatchQueue.once 方法 所以手動擴展了一個 方便使用

extension DispatchQueue {private static var _onceTracker = [String]()public class func once(token: String, block: () -> ()) {objc_sync_enter(self)defer {objc_sync_exit(self)}if _onceTracker.contains(token) {return}_onceTracker.append(token)block()}func async(block: @escaping ()->()) {self.async(execute: block)}func after(time: DispatchTime, block: @escaping ()->()) {self.asyncAfter(deadline: time, execute: block)} }

?

轉載于:https://my.oschina.net/iceTear/blog/2208854

總結

以上是生活随笔為你收集整理的关于Swift4.0 Method Swizzling(iOS的hook机制)使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。