接上一篇 http://www.cnblogs.com/ddavidXu/p/5924597.html

转载来源http://www.jianshu.com/p/6b905584f536

http://southpeak.github.io/2014/10/30/objective-c-runtime-2/

runtime的黑魔法,就是可以实现交换两个方法的实现,这就意味着我们可以修改系统的方法实现。

栗子:当UIViewController及其子类的对象调用viewWillAppear时,都会打印一条日志信息。

#import <objc/runtime.h>

@implementation UIViewController (Tracking)

+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
// When swizzling a class method, use the following:
// Class class = object_getClass((id)self); SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(xxx_viewWillAppear:); Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod)); if (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
} #pragma mark - Method Swizzling - (void)xxx_viewWillAppear:(BOOL)animated {
[self xxx_viewWillAppear:animated];
NSLog(@"viewWillAppear: %@", self);
} @end

因为关于method swizzling方法的介绍非常多,就不详细说了,

大致原理图

需要注意一下几点

  • Swizzling应该总是在+load中执行

  • Swizzling应该总是在dispatch_once中执行

原因,method swizzling会影响到类的全局状态,避免在并发处理中出现竞争的情况,不管有多少个线程,确保代码只被执行一次。

选择器(selector)、方法(method)和实现(implementation)

  • Selector(typedef struct objc_selector *SEL):用于在运行时中表示一个方法的名称。一个方法选择器是一个C字符串,它是在Objective-C运行时被注册的。选择器由编译器生成,并且在类被加载时由运行时自动做映射操作。

  • Method(typedef struct objc_method *Method):在类定义中表示方法的类型

  • Implementation(typedef id (*IMP)(id, SEL, …)):这是一个指针类型,指向方法实现函数的开始位置。这个函数使用为当前CPU架构实现的标准C调用规范。每一个参数是指向对象自身的指针(self),第二个参数是方法选择器。然后是方法的实际参数。

理解,一个类维护一个运行时可接收的消息分发表,分发表中的每个入口是一个方法method,其中可以是一个特定名称,即选择器SEL,其对应一个实现IMP。即指向底层C函数的指针。

还要注意几点

  • 总是调用方法的原始实现,不调用原始方法,很有可能影响到程序的其他部分
  • 给自定义的方法加前缀,避免方法名冲突
  • 理解工作原理
  • 小心操作,万一版本一改就☀️了

    runtime 第四部分method swizzling的更多相关文章

    1. 理解Objective-C Runtime(四)Method Swizzling

      Objective-C对象收到消息之后,究竟会调用何种方法需要在运行期间才能解析出来.那你也许会问:与给定的选择子名称相应的方法是不是也可以在runtime改变呢?没错,就是这样.若能善用此特性,则可 ...

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

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

    3. Objective-C Runtime 运行时之四:Method Swizzling(转载)

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

    4. runtime实践之Method Swizzling

      利用 Objective-C 的 Runtime 特性,我们可以给语言做扩展,帮助解决项目开发中的一些设计和技术问题.这一篇,我们来探索一些利用 Objective-C Runtime 的黑色技巧.这 ...

    5. Objective-C运行时编程 - 方法混写 Method Swizzling

      摘要: 本文描述方法混写对实例.类.父类.不存在的方法等情况处理,属于Objective-C(oc)运行时(runtime)编程范围. 编程环境:Xcode 6.1.1, Yosemite,iOS 8 ...

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

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

    7. Objective-C 利用OC的消息机制,使用Method Swizzling进行方法修改

      功能:修改父类不可修改函数方法,函数方法交换 应用场景:假如我们使用的他人提供一个的framework,.m已被打包成二进制.a无法修改源码,只留下.h头文件,那假如代码中某个函数出现了问题可以通过这 ...

    8. Method Swizzling (方法调配)

      Method Swizzling是改变一个selector的实际实现的技术.通过这一技术,我们可以在运行时通过修改类的分发表中selector对应的函数,来修改方法的实现. 例如,我们想跟踪在程序中每 ...

    9. iOS中AOP与Method Swizzling 项目中的应用

      引子:项目中需要对按钮点击事件进行统计分析,现在项目中就是在按钮的响应代码中添加点击事件,非常繁琐.所以使用了AOP(面向切面编程),将统计的业务逻辑统一抽离出来. 项目中添加的开源库:https:/ ...

    随机推荐

    1. 初识redis数据类型

      初识redis数据类型 1.String(字符串) string是redis最基本的类型,一个key对应一个value. string类型是二进制安全的.意思是redis的string可以包含任何数据 ...

    2. codevs 3110 二叉堆练习3

      3110 二叉堆练习3 http://codevs.cn/problem/3110/ 题目描述 Description 给定N(N≤500,000)和N个整数(较有序),将其排序后输出. 输入描述 I ...

    3. React数据流和组件间的沟通总结

      今天来给大家总结下React的单向数据流与组件间的沟通. 首先,我认为使用React的最大好处在于:功能组件化,遵守前端可维护的原则. 先介绍单向数据流吧. React单向数据流: React是单向数 ...

    4. appium常用方法整理

      1.相对坐标解锁九宫格 应用场景 QQ解锁屏幕如上,可见九个按键在同一个View下面,要实现解锁,用press   moveTo  release  perform方法 实现代码如下: WebElem ...

    5. 国内git项目托管平台

      以前一直使用github托管项目,最近换了阿里云的vps,连接github出奇的慢,找了一下国内的代码托管平台. 有几个都不错,我刚好有csdn的账号,就试了一下csdn的托管平台,创建一个项目,发现 ...

    6. 【USACO 3.2】Spinning Wheels(同心圆旋转)

      题意: 5个同心圆,告诉你角速度,每个圆有1至5个楔,告诉你起点和宽度.求最早时间如果有的话使得存在某个角度经过5个圆的楔. 题解: 最重要的是要意识到,360秒钟后,每个圆都回到了原来的位置. 我的 ...

    7. 在mysql 查询语句中将时间戳格式转化为年月日格式

      SELECT  FROM_UNIXTIME('时间戳的字段名称', '%Y-%m-%d %H:%i:%s')   FROM `表名` http://www.cnblogs.com/tdalcn/arc ...

    8. Linux工具入门:make工具与Makefile文件

      1. make工具 利用make工具可以自动完成编译工作,这些工作包括: 如果修改了某几个源文件,则只重新编译这几个源文件 如果某个头文件被修改了,则重新编译所有包含该头文件的源文件 利用这种自动编译 ...

    9. Java相关书籍分享

      Java核心技术(卷1):基础知识(原书第9版) [Core Java Volume I-Fundamentals (Ninth Edition)].pdf Java核心技术(卷2):高级特性(原书第 ...

    10. 【codeforces 442B】 Andrey and Problem

      http://codeforces.com/problemset/problem/442/B (题目链接) 题意 n个人,每个人有p[i]的概率出一道题.问如何选择其中s个人使得这些人正好只出1道题的 ...