写在前面 关于 Method Swizzling 这个东西,已经有很多高人写了详细的文章来介绍,我就不再班门弄斧,往深了说了。 而且不作延伸的话,这项技术本身也没有复杂到要长文论述的地步。...Method Swizzling 也叫做“方法调配”、“方法混合”、“方法调和”,是用来互换两个方法的实现的技巧。..."]) print("-----Swizzling 之前-----") print(arr.containsObject("Swift")) // true...NSArray.swizz() // 方法互换 print("-----Swizzling 之后-----") print...Swift")) // 先输出 index,再 true NSArray.swizz() // 方法再换回来 print("-----Swizzling
iOS runtime swift中的Swizzling方法交换 背景知识 Swift 是一种强类型语言。即默认类型是安全的静态类型。...Swift中的动态性可以通过OC运行时来获得,动态性最常用的就是方法替换(Method Swizzling)。...swift动态修饰符 @objc 将Swift函数暴露给OC运行时,但是它仍然不能保证完全动态,编译器会尝试去对它做静态优化 dynamic 动态功能修饰符,它能保证函数,属性可以获得动态性 Swizzling...{ UIApplication.runOnce return super.next } } /// swizzling协议 在需要交换方法的类中遵循此协议,实现方法.../// swizzling协议 protocol SwizzlingProtocol { static func inject() } /// 管理类 class SwizzlingManager
method-swizzling 是什么?...method-swizzling的含义是方法交换,其主要作用是在运行时将一个方法的实现替换成另一个方法的实现,这就是我们常说的iOS黑魔法, 在OC中就是利用method-swizzling实现AOP,...bIMP,但是bIMP不一定指向aIMP method_exchangeImplementations:交换两个方法的实现,即 aIMP -> bIMP, bIMP -> aIMP 坑点1:method-swizzling...使用过程中的一次性问题 所谓的一次性就是:mehod-swizzling写在load方法中,而load方法会主动调用多次,这样会导致方法的重复交换,使方法sel的指向又恢复成原来的imp的问题 解决方案...所以如果想对NSArray进行Swizzling,必须获取到其“真身”进行Swizzling,直接对NSArray进行操作是无效的。
我本来想集中写成一篇文章的,但是最后发现实在是太长,而且不利于阅读,最后分成了如下几篇: RunTime 之使用前须知 RunTime 之常规操作 RunTime 之消息处理与消息转发 RunTime 之Method Swizzling...RunTime 之其他实践运用 ---- isa swizzling 的应用 KVO Method Swizzling API 说明 Method Swizzling技术它能够让我们在运行时替换已有方法来实现我们的一些需求...而 Method Swizzling 可以交换两个方法的实现。...应用一:拦截系统自带的方法调用Method Swizzling 一般是在load方法中进行,确保最先被调用。+load方法会在Appdelegate的方法之前执行,是最先执行的方法。...使用场景 Method Swizzling 可以重写某个方法而不用继承,同时还可以调用原先的实现。通常的做法是在category中添加一个方法(当然也可以是一个全新的class)。
通过本文,您将了解到: Method Swizzling(动态方法交换)简介 Method Swizzling 使用方法(四种方案) Method Swizzling 使用注意 Method Swizzling...Method Swizzling(动态方法交换)简介 Method Swizzling 用于改变一个已经存在的 selector 实现。...Method Swizzling 使用注意 Method Swizzling 之所以被大家称为黑魔法,就是因为使用 Method Swizzling 进行方法交换是一个危险的操作。...谨慎对待 Method Swizzling。 使用 Method Swizzling,会改变非自己拥有的代码。我们使用 Method Swizzling 通常会更改一些系统框架的对象方法,或是类方法。...所以 Method Swizzling 的顺序不能保证,那么就不能保证 Method Swizzling 后方法的调用顺序是正确的。
Method Swizzling Method Swizzling是改变一个selector的实际实现的技术。
那么,method swizzling怎么写呢?...1、 method swizzling是非原子性的,也就是说method swizzling是非线程安全的。 ...,所以所有的method swizzling都应该写在+ load方法里。...2、method swizzling可能会改变原来类中的代码 使用method swizzling是为了改变原有的方法,如果你只为了一个地方替换了方法,可这时所有用到这个方法的地方都受到了改变,带来的危害是无法估量的...3、method swizzling可能会造成方法名冲突 想象一下,如果你在类中用method swizzling中替换了一个方法,又在category中又扩展了这个方法,这时候就会出现方法名冲突,
[logo.jpeg] iOS开发之 Method Swizzling 深入浅出 ======= 只要善用Google,网上有很多关于Method Swizzling的Demo,在这里我就不打算贴代码了...Method Swizzling 我们可以使用苹果的“黑魔法”Method Swizzling,Method Swizzling本质上就是对IMP和SEL进行交换。...Method Swizzling原理 Method Swizzing是发生在运行时的,主要用于在运行时将两个Method进行交换,我们可以将Method Swizzling代码写到任何地方,但是只有在这段...所以如果想对NSArray进行Swizzling,必须获取到其“真身”进行Swizzling,直接对NSArray进行操作是无效的。...应该总在+load中执行 Swizzling应该总是在dispatch_once中执行 Swizzling在+load中执行时,不要调用[super load]。
不要在load里面取加载对象,因为我们再load调用的时候根本就不确定我们的对象是否已经初始化了,所以不要去做对象的初始化 I Method Swizzling基础 在Objective-C的Runtime...使用Method Swizzling交换方法,其实就是修改了objc_method结构体中的mthod_imp,即改变了method_name和method_imp的映射关系 在这里插入图片描述 1.1...Method swizzling 修改了类的消息分发列表使得已经存在的 selector 映射到另一个实现 implementation,同时重命名了原生方法的实现对应一个新的 selector。...1.3 Method swizzling的时机 如果使用恰当,Method swizzling 还是很安全的,一个简单安全的方法是,仅在load中swizzle ,在 dispatch_once 中完成...的能力 Method Swizzling 的封装 -------------------- /** 让所有继承自NSObject的子类,都具有Method Swizzling的能力。
dealloc{ [self.person removeObserver:self forKeyPath:@"nickName"]; } 使用需要及时进行合法销毁; 3、KVO原理 3.1 isa-swizzling...这个类,这就是isa-swizzling。
达到一个不同类进行 Method Swizzling 的目的。
Method swizzling 用于改变一个已经存在的 selector 的实现。这项技术使得在运行时通过改变 selector 在类的消息分发列表中的映射从而改变方法的掉用成为可能。...有很多的场景选择method swizzling 会是很合适的解决方式,这显然也会让 Objective-C 开发者的技术变得越来越成熟。...到此我们已经知道为什么,应该在哪些地方使用 method swizzling,下面介绍如何使用 method swizzling: +load vs +initialize swizzling应该只在+...dispatch_once ** swizzling 应该只在 dispatch_once 中完成** 由于 swizzling 改变了全局的状态,所以我们需要确保每个预防措施在运行时都是可用的。...好的程序员应该对这里出现的方法的递归调用有所警觉,这里我们应该理清在 method swizzling 后方法的实现究竟变成了什么。
注意要点 Swizzling应该总在+load中执行 Swizzling应该总是在dispatch_once中执行 Swizzling在+load中执行时,不要调用[super load]。...思路:对NSArray的objectAtIndex:方法进行Swizzling,替换一个有处理逻辑的方法。但是,这时候还是有个问题,就是类簇的Swizzling没有那么简单。...所以如果想对NSArray进行Swizzling,必须获取到其“真身”进行Swizzling,直接对NSArray进行操作是无效的。...这是因为Method Swizzling对NSArray这些的类簇是不起作用的。 因为这些类簇类,其实是一种抽象工厂的设计模式。...所以如果我们对NSArray类进行Swizzling操作其实只是对父类进行了操作,在NSArray内部会创建其他子类来执行操作,真正执行Swizzling操作的并不是NSArray自身,所以我们应该对其
2.Method Swizzling使用 一般我们使用都是新建一个分类,在分类中进行Method Swizzling方法的交换。...这将成为Method Swizzling的最佳实践。 这里有一个很容易犯的错误,那就是继承中用了Swizzling。如果不写dispatch_once就会导致Swizzling失效!...3.Swizzling在+load中执行时,不要调用[super load] 原因同注意点二,如果是多继承,并且对同一个方法都进行了Swizzling,那么调用[super load]以后,父类的Swizzling...然后再进行class_replaceMethod来实现Swizzling。 这是Swizzling需要判断的一点。...Isa Swizzling 前面第二点谈到了黑魔法Method Swizzling,本质上就是对IMP和SEL进行交换。
App异常加载占位图通用类封装 全局修改导航栏返回按钮 (去掉title) 以下是使用内容: `NSObject`的`Category`里实现方法替换,方便需要的类直接调用: // NSObject+Swizzling.h...methodSwizzlingWithOriginalSelector:(SEL)originalSelector bySwizzledSelector:(SEL)swizzledSelector; // NSObject+Swizzling.m...__NSArrayM NSDictionary __NSDictionaryI NSMutableDictionary __NSDictionaryM // NSMutableArray+Swizzling.m...)action to:(id)target forEvent:(UIEvent *)event 改用 afterDelay 调用,并添加标志位,防止暴力点击,具体代码如下: // UIButton+Swizzling.m...forEvent:event]; // 执行系统的原有方法 } // 还有些属性,没添加,详情见Demo `UILabel`的`Category`中拦截初始化方法,并设置font // UILabel+Swizzling.m
Method swizzling 修改了类的消息分发列表使得已经存在的 selector 映射了另一个实现 implementation,同时重命名了原生方法的实现为一个新的 selector。 ?...NSPipster的Method Swizzling Method Swizzling需要注意的是: (1)应该总在+load中执行,+load会在类初始加载时调用,和+initialize比较+load...(2) dispatch_once中执行:swizzling会改变全局状态,所以在运行时采取一些预防措施,使用dispatch_once就能够确保代码不管有多少线程都只被执行一次。...这将成为method swizzling的最佳实践。 5.2日志打印 快速熟悉项目。...,不管是现在热门的THEOS还是iOSOpenDev都是Method Swizzling的封装,点击iOSOpenDev使用的CaptainHook就可以看到都是Method Swizzling 各种方法
一、前言 1、黑魔法 Runtime有个黑魔法,可以通过method swizzling在运行时将系统API进行替换,可以再自定义的方法中进行埋点。...所以 通过监测dealloc方法就可以监测内存泄漏 二、Runtime黑魔法 可以通过method swizzling在运行时将系统API进行替换 void monitor_exchangeInstanceMethod...在load方法中,将UIViewController的生命周期里的几个method都通过method swizzling替换成我们自定义的方法,在自定义的方法中进行埋点,从而达到统计和监测的目的。...),@(pass)); self.didLoadTime = @(0); } [self ht_viewDidAppear:animated]; } 通过method swizzling
在 iOS 中,要想实现相似的效果也很简单,利用 oc 的动态性,通过 swizzling method 改变目标函数的 selector 所指向的实现,然后在新的实现中实现附加的操作,完成之后再回到原来的处理逻辑...4.如果baseClass是MetaClass或者被KVO过的Class,则不必再生成subClass,直接在其自身上进行method swizzling。...5.如果不是上述3、4 所述情况,默认情况下需要对被hook的Class进行”isa swizzling”: 1)通过subclass = objc_allocateClassPair(baseClass...动态创建一个被hook类(TestClass)的子类(TestClass_Aspects); 2)然后对子类(TestClass_Aspects)的forwardInvocation:进行method swizzling
) Method Swizzling 的使用需要谨慎,因为一不小心可能就会导致无法排查的Bug,毕竟它替换的是官方的API,有些API内部做了什么事情,很难完全把握。...onceToken; dispatch_once(&onceToken, ^{ Class class = [self class]; // When swizzling...} 以上示例代码摘自:Objective-C Runtime 运行时之四:Method Swizzling 关于Method Swizzling,他是把两个方法的实现部分互换了。...} 假如上面这俩方法用method swizzling 替换后,我们调用-xxx_viewWillAppear:会打印这是原来的方法;而调用-viewWillAppear:会打印xxx_viewWillAppear...关于Method Swizzling更多的注意点请看原文Method Swizzling 3.对象关联(Associated Objects) 对象关联(或称为关联引用)本来是Objective-C 运行时的一个重要特性
的,如果有不清楚的地方,可以看看这里method swizzling--by冰霜或者自行查阅。...// 7) 如果当前class对于resume的实现和父类不一样(类似iOS7上的情况),并且当前class的resume实现和af_resume不一样,才进行method swizzling...方法的类,另外__NSCFLocalSessionTask中的resume和suspend并没有调用其父类(即__NSCFURLSessionTask)方法,这也意味着两个类的方法都需要进行method swizzling...这也意味着其是唯一需要进行method swizzling的类 因为NSURLSessionTask并不是在每个iOS版本中都存在,所以把这些放在此处(即load函数中),比如给一个dummy class...请注意这行判断: // 7) 如果当前class对于resume的实现和父类不一样(类似iOS7上的情况),并且当前class的resume实现和af_resume不一样,才进行method swizzling
领取专属 10元无门槛券
手把手带您无忧上云