OC- Method Swizzling
2016-03-12 20:12
309 查看
1、Method Swizzling 原理
Objective-C 的每一个方法都有一个唯一对应的SEL,而方法是运行时绑定的,利用这些特性,我们可以在运行时调换方法的实现。前面我们说过,IMP 是一个函数指针,通过SEL获得指向方法的入口地址。下面是正常情况下SEL对应IMP函数指针的情况:
Method Swizzling 实现的原理就是调换IMP的指向:
2、Method Swizzling 应用
3、注意事项
1、在+load方法中使用;
2、命名规范,带前缀;
3、在dispatch_once中执行,保证代码不管在多少个线程情况下,只被执行一次。
Objective-C 的每一个方法都有一个唯一对应的SEL,而方法是运行时绑定的,利用这些特性,我们可以在运行时调换方法的实现。前面我们说过,IMP 是一个函数指针,通过SEL获得指向方法的入口地址。下面是正常情况下SEL对应IMP函数指针的情况:
Method Swizzling 实现的原理就是调换IMP的指向:
2、Method Swizzling 应用
#import "UIViewController+MethodSwizzling.h" #include <objc/runtime.h> @implementation UIViewController (MethodSwizzling) /* +load 方法会在类加入运行期调用,这是把方法调配放在+load方法里面的原因 */ + (void)load { static dispatch_once_t onceToken; /*单例保证并行情况下不会有问题*/ dispatch_once(&onceToken, ^{ Class class = [self class]; SEL originalSelector = @selector(viewWillAppear:); SEL swizzledSelector = @selector(my_viewWillAppear); /*获取原来的方法*/ Method originalMethod = class_getInstanceMethod(class, originalSelector); /*获取要替换的方法*/ Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); /*originalSelector是否有实现,如果存在返回YES,不存在返回NO*/ BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); if (success) { /*修改要替换的方法实现为原有实现*/ class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { /*表示待交换的两个方法的实现*/ method_exchangeImplementations(originalMethod, swizzledMethod); } }); } #pragma mark - Method Swizzling /* 看上去会递归调用,进入死循环。但是这个方法是准备和viewWillAppear方法交换的。在运行期,my_viewWillAppear 选择子实际上对应于原有的viewWillAppear方法实现。 */ - (void)my_viewWillAppear { [self my_viewWillAppear]; NSLog(@"%s", __func__); } @end
3、注意事项
1、在+load方法中使用;
2、命名规范,带前缀;
3、在dispatch_once中执行,保证代码不管在多少个线程情况下,只被执行一次。
相关文章推荐
- 第二周学习进度条
- Interview(位运算)
- 重装电脑问题 记事1
- OC中的一些基础知识,不对的地方还请指正!
- hdu 5546 Ancient Go(★)
- C#中类中构造函数的执行序列
- Java集合源码学习笔记(二)ArrayList分析
- 第2周作业 2013551628 邱鹏
- 杭电oj 2032 杨辉三角
- HDU 1496 整数Hash
- adb failed to start daemon 彻底解决
- CoreData笔记
- Linux下is not in the sudoers file解决方法
- 单例模式的七种写法
- [国嵌攻略][139][输入子系统原理分析]
- ul和ol的一些知识
- Codeforces Round #307 (Div. 2) 551E - GukiZ and GukiZiana 分块
- 第二周项目3输出图形(d)
- ssh 传送下载文件
- 优先队列模板(两种方式)(3785)