iOS_Runtime2_方法交换
来源:互联网 发布:人工智能就业 知乎 编辑:程序博客网 时间:2024/06/04 19:25
- 利用
Runtime
实现的方法交换,主要是为了修改系统的方法实现。 - Objective-C 提供了一下API用于动态替换类方法或者实例方法的实现:
class_replaceMethod
替换类方法的定义method_exchangeImplementations
交换两个方法的实现method_setImplementation
设置一个方法的实现
注:class_replaceMethod
试图替换一个不存在的方法时候,会调用class_addMethod
为该类增加一个新方法
以UIImage类目为例,实现类方法,以及对象方法的实现交换。
代码示例如下:
// UIImage+Image.h@interface UIImage (Image)// 对象方法- (void)sayOne;- (void)sayTwo;@end// UIImage+Image.m#import <objc/message.h>@implementation UIImage (Image)+ (void)load{ // 修改类方法实现示例: Method imageNamedMethod = class_getClassMethod(self, @selector(imageNamed:)); Method xmg_imageNamedMethod = class_getClassMethod(self, @selector(xmg_imageNamed:)); // 利用runtime实现方法的交换 method_exchangeImplementations(imageNamedMethod, xmg_imageNamedMethod); // 修改对象方法实现示例: Method method1 = class_getInstanceMethod(self, @selector(sayOne)); Method method2 = class_getInstanceMethod(self, @selector(sayTwo)); method_exchangeImplementations(method1, method2);}+ (UIImage *)xmg_imageNamed:(NSString *)name{ // 由于已经实现了方法交换,故[UIImage xmg_imageNamed:name]的内部调用实际上走的是[UIImage imageNamed:name]原本的内部实现。 UIImage *image = [UIImage xmg_imageNamed:name]; if (image) { NSLog(@"加载成功"); } else { NSLog(@"加载失败"); } return image;}- (void)sayOne{ NSLog(@"One");}- (void)sayTwo{ NSLog(@"Two");}@end// 调用示例:#import "UIImage+Image.h" // 导入此类目UIImage *image = [[UIImage alloc]init];[image sayOne]; //输出:Two[UIImage imageNamed:@"one.png"]; //输出:加载成功
总结:
Method class_getInstanceMethod(Class cls, SEL name)
获取类方法。参数一Class cls
:获取哪个类的方法;参数二SEL name
:获取类的哪个方法;返回值类型为Method
。Method class_getInstanceMethod(Class cls, SEL name)
获取对象方法。参数一Class cls
:获取哪个类的方法;参数二SEL name
:获取类的哪个对象方法;返回值类型为Method
。void method_exchangeImplementations(Method m1, Method m2)
替换方法m1与方法m2的实现。- 在类目中,最好不要重写系统方法。一旦重写,将会把系统方法实现给干掉,因为分类不是继承父类,而是继承NSObject,因此super不是改类的方法,而是直接覆盖掉了父类的行为。
+ (void)load
与+ (void)initialize
的区别:+ (void)load
:当类加载进内存的时候调用,而且不管有没有子类,都只会调用一次,在main函数之前调用。- 用途:(1)可以新建类在该类中实现一些配置信息。(2)runtime交换方法的时候,因为只需要交换一次方法,所有可以在该方法中实现交换方法的代码,用于只实现一次的代码 。
+ (void)initialize
:当类被初始化的时候调用,可能会被调用多次,若是没有子类,则只会调用一次,若是有子类的话,该方法会被调用多次,若是子类的继承关系,先会调用父类的+ (void)initialize
方法,然后再去调用子类的+ (void)initialize方法
(若是继承关系,调用某个方法的时候,先会去父类中查找,若是父类中没有方法的实现就去子类中查找)- 用途:(1)在设置导航栏的全局背景的时候,只需要设置一次,可以重写该方法设置,最好是在该方法判断子类,若是自己,则实现设置全局导航栏的方法,若不是自己则跳过实现。(2)在创建数据库代码的时候,可以在该方法中去创建,保证只初始化一次数据库实例,也可以用
dispatch
或是懒加载的方法中初始化数据库实例,也能保证只初始化一次数据库实例。其中也可以在+ (void)initialize
方法中用dispatch
也能保证即使有子类也只会初始化一次。
iOS_Runtime1_消息发送机制
iOS_Runtime3_动态添加方法
iOS_Runtime4_动态添加属性
iOS_Runtime5_消息转发
iOS_Runtime6_字典转化为模型应用
代码地址:
https://github.com/FlyingKuiKui/RunTime.git
阅读全文
0 0
- iOS_Runtime2_方法交换
- 交换方法
- 交换方法
- 交换数据方法总结
- 交换变量的方法
- 交换两个变量方法
- swizzle交换方法名
- 两个整数交换方法
- 交换视图层次方法
- runtime 方法交换
- runtime 方法交换
- Runtime -- 交换方法
- runtime交换方法
- 交换两数方法
- 交换变量方法
- 数据交换方法比较
- runtime方法交换
- Runtime 学习-方法交换
- odoo开发所遇到问题集合
- MySQL大表优化方案
- 用aardio给python写个图形界面
- Java:集合框架(四)Map详解及代码示例
- js中cookie的用法
- iOS_Runtime2_方法交换
- 介绍几种java中网络通信的方式
- 集合的几种遍历方式
- mybatis 获取插入数据的自增id值
- 计算机视觉领域的一些牛人博客
- C51 串口收发,printf, 接收字符串
- java调用dll时回调函数的实现(jna)
- 训练日记8.21
- BZOJ4145: [AMPPZ2014]The Prices