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机制)使用相关推荐

  1. iOS黑魔法--Method Swizzling

    参考链接: iOS黑魔法-Method Swizzling iOS 黑魔法 - 专题 - 简书 Method Swizzle黑魔法,修改 ios 系统类库方法

  2. Objective-C Runtime 运行时之四:Method Swizzling

    理解Method Swizzling是学习runtime机制的一个很好的机会.在此不多做整理,仅翻译由Mattt Thompson发表于nshipster的Method Swizzling一文. Me ...

  3. Objective-C的hook方案(一): Method Swizzling

    在没有一个类的实现源码的情况下,想改变其中一个方法的实现,除了继承它重写.和借助类别重名方法暴力抢先之外,还有更加灵活的方法吗?在Objective-C编程中,如何实现hook呢?标题有点大,计划分几 ...

  4. iOS 开发:『Runtime』详解(二)Method Swizzling

    本文用来介绍 iOS 开发中『Runtime』中的黑魔法Method Swizzling. 通过本文,您将了解到: Method Swizzling(动态方法交换)简介 Method Swizzlin ...

  5. 【原】iOS动态性(三) Method Swizzling以及AOP编程:在运行时进行代码注入

    概述 今天我们主要讨论iOS runtime中的一种黑色技术,称为Method Swizzling.字面上理解Method Swizzling可能比较晦涩难懂,毕竟不是中文,不过你可以理解为" ...

  6. iOS总结-Runtime篇之黑魔法Method Swizzling的滥用会有危险吗

    参考https://www.jianshu.com/p/19c5736c5d9a, http://blog.sina.com.cn/s/blog_a343f32b0101en4o.html runti ...

  7. iOS总结-Runtime篇之用途及面试题的总结一黑魔法Method Swizzling

    runtime的用途基本分下面几类: 实现多继承Multiple Inheritance 上一篇里面的最后利用methodSignatureForSelector来进行一次转发,在forwardInv ...

  8. Method Swizzling的各种姿势

    因为Objective-C的runtime机制, Method Swizzling这个黑魔法解决了我们实际开发中诸多常规手段所无法解决的问题, 比如代码的插桩,Hook,Patch等等. 我们首先看看 ...

  9. Swift4.0复习特性、编译标志和检查API的可用性

    1.Swift中的特性: @引出,后面紧跟特性名,圆括号带参数即可. @attribute(args) avaiable: 指明对象,函数,类型的可用性. @available(iOS 10.0, m ...

最新文章

  1. python使用什么注释语句和运算-Python代码注释的用法和意义
  2. 以后版本网卡命名规则
  3. ElementUI中显示是否以及SpringBoot中怎样存储实体类属性和数据库怎样设计字段
  4. FLV视频文件格式分析
  5. Kubernetes pod状态出现ImagePullBackOff的原因
  6. js返回上一页并刷新
  7. SAP License:SAP权限原理与授权对象
  8. 计算几何-判断两条线段是否相交
  9. Gitlab-API各状态码解释
  10. 万能解压器安卓版_解压zip app下载-解压zip(手机解压缩软件)下载11.5.4 安卓版-西西软件下载...
  11. lol登录服务器时显示乱码,lol服务器变成乱码 | 手游网游页游攻略大全
  12. 计算机病毒是指源程序还是特殊小程序,2015年9月计算机一级考试Msoffice上机模拟题(五)...
  13. SQL三个表关联查询
  14. 【办公自动化Excel】开发工具的使用
  15. 一本书让你知道互联网思维 个人总结
  16. write combining
  17. CodeForces - 1413C Perform Easily(双指针)
  18. windows下安装mpich2
  19. android开发指纹解锁,Android-指纹解锁技术
  20. 操作系统--时间片轮转调度算法(RR算法)

热门文章

  1. db2 如何导出insert语句_《MySQL 入门教程》第 23 篇 DML 语句之插入数据
  2. java stringbuilder appendline_StringBuilder
  3. ssm中使用hibernate-validator验证BO
  4. centos7 安装oracle jdk 与openjdk 实现切换
  5. PHP的echo和print小谈
  6. 更改系统的默认安装路径
  7. 内存映射文件(File Mapping)API
  8. android 7.0独立升级,爆料:Android 7.0用户将可自行升级!
  9. easyui框架前后端交互_Vue+ElementUI+.netcore前后端分离框架开发项目实战
  10. jvm类加载机制_面试:对于JVM类加载机制深度解析