iOS-Swizzle
最后更新:2017-06-21
一、先说结论
void swizzleMethod(Class cls, SEL originalSelector, SEL swizzledSelector)
{
Method originalMethod = class_getInstanceMethod(cls, originalSelector);
Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);
BOOL didAddMethod =
class_addMethod(cls,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(cls,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
二、代码分析
2.1 class_getInstanceMethod()
获取某个类实例的方法, 如果该类实例没有此方法, 则返回NULL
Method swizzleMethod = class_getInstanceMethod([Person class], @selector(run));
if (swizzleMethod == NULL) {
NSLog(@"NULL");
}
参数解释
class_getInstanceMethod(Class cls, SEL name)
cls: 获取方法的类
name: 方法的名称
2.2 class_addMethod()

参数解释
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
cls: 获取方法的类
name: 添加的方法方法的名称
imp: 方法的实现,也就一个指向方法的指针
const char *types: 定义了返回值类型和参数类型的字符串(下面会提到)
返回值
YES: 增加方法成功
NO: 增加方法失败,例如 (如果目标类(Person) 实现了该方法,那么会返回 NO)
注意点
- class_addMethod 能够覆盖父类的实现的;
如果目标类有实现了该方法,class_addMethod就会失败
class_addMethod will add an override of a superclass's implementation
处理警告问题
参考: https://stackoverflow.com/questions/6224976/how-to-get-rid-of-the-undeclared-selector-warningvoid sayHello(id self, SEL _cmd, NSString *word)
{
NSLog(@"%@", word);
} - (void)viewDidLoad {
[super viewDidLoad]; #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
class_addMethod([Person class], @selector(resolveThisMethodDynamically:), (IMP)sayHello, "v@:@");
Person *p = [[Person alloc] init];
[p performSelector:@selector(resolveThisMethodDynamically:) withObject:@"hello"];
#pragma clang diagnostic pop }需要动态调用,因为通过运行时添加的方法,直接调用 编译不过的
正确做法:
[p performSelector:@selector(resolveThisMethodDynamically:) withObject:@"hello"]; 错误做法,编译不过
[p resolveThisMethodDynamically:@"hello"];
参 imp 默认自带两个参数, id类型 以及 SEL 类型
void sayHello(id self, SEL _cmd, ...)
2.3 参数 const char *types 解释
v 表示的是void 类型
i 表示整数类型
@ 表示一个对象
: 表示一个方法
v@: 表示的是返回值类型是void, 一个参数是对象(id self),另一个参数为方法 (SEL _cmd)
v@
/////////////////////////////////////////////////////////////////////////////////////////////////// ... 什么是runtime? 1> runtime是一套底层的C语言API(包含很多强大实用的C语言数据类型.C语言函数)2> 实际上,平时我们编写的OC代码,底层都是基于runtime实现的* ... 1.是否可以把比较耗时的操作放在通知中心中? 通知在哪一个线程发的,那么对通知事件的处理就在同一个线程中进行; 如果在异步线程发的通知,那么可以执行比较耗时的操作: 如果在主线程发的通知,那么就不 ... ios runtime swizzle @implementation NSObject(Extension) + (void)swizzleClassMethod:(Class)class orig ... Method Swizzle黑魔法,修改 ios 系统类库方法 版权声明:本文为博主原创文章,未经博主允许不得转载. 一般来说,系统提供的方法已经足够开发了,但是有的时候有些需求用普通方法不好做. ... 开源 iOS 项目分类索引大全 GitHub 上大概600个开源 iOS 项目的分类和介绍,对于你挑选和使用开源项目应该有帮助 系统基础库 Category/Util sstoolkit 一套Cate ... 概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ... 1:iOS视图控制对象生命周期 init-初始化程序 viewDidLoad-加载视图 viewWillAppear-UIViewController对象的视图即将加入窗口时调用: viewDidAp ... 概述 今天我们主要讨论iOS runtime中的一种黑色技术,称为Method Swizzling.字面上理解Method Swizzling可能比较晦涩难懂,毕竟不是中文,不过你可以理解为“移花接木 ... Runtime是想要做好iOS开发,或者说是真正的深刻的掌握OC这门语言所必需理解的东西.最近在学习Runtime,有自己的一些心得,整理如下,一为 查阅方便二为 或许能给他人一些启发,三为 希望得到 ... JPA-style positional param was not an integral ordinal 多是sql之间的空格问题,或者sql拼接问题. 字符串与字符串直接相加要加空格 安装包:mysqlreport-3.5.tgz 下载地址:http://hackmysql.com/scripts/mysqlreport-3.5.tgz 安装办法:[root@nagios ~]# ... 黄色感叹号(有冲突):--这是有冲突了,冲突就是说你对某个文件进行了修改,别人也对这个文件进行了修改,别人抢在你提交之前先提交了,这时你再提交就会被提示发生冲突,而不允许你提交,防止你的提交覆盖了别人 ... nrm安装与配置:https://blog.csdn.net/anway12138/article/details/79455224 这个错误是将work offline打勾引起的. 这个是离线工作模式,相当于断网,远程的jar会拉不下来. 幂等指的就是执行多次和执行一次的效果相同,主要是为了防止数据重复消费.MQ中为了保证消息的可靠性,生产者发送消息失败(例如网络超时)会触发 "重试机制",它不是生产者重试而是MQ自 ... 一些常用的: CKEditor UEEditor TinyEditor KindEditor 下载: http://kindeditor.net/down.php 使用方法: <textarea ... maven jar包下载命令行方式 在STS中下载JAR包时经常卡住无法继续下载,这时可以用命令行方式进行下载.在终端中今入到该项目的根目录下,然后mvn clean;mvn install;等待下载 ... Given an unsorted integer array, find the smallest missing positive integer. Example 1: Input: [1,2, ... 预留的广告位! 下载该pdf文件,然后在adobe reader 的"视图"中使用"全屏模式"播放该幻灯片 #include <iostream> ...iOS-Swizzle的更多相关文章
随机推荐