ios runtime void method_exchangeImplementations
2016-04-26 18:26
381 查看
http://blog.sina.com.cn/s/blog_9d25acc60102vts9.html
如果对Runtime有一定了解的话,一定听说过或者用过这个函数:
它通常叫做method swizzling,算是ObjC的"黑魔法"了,作用就是在程序运行期间动态的给两个方法互换实现,比如有这样一种使用场景:
我们的程序中有许多个ViewController,我想在对项目改动最小的情况下,在当每个Controller执行完ViewDidLoad以后就在控制台把自己的名字打印出来,方便我去做调试或者了解项目结构。
有许多朋友会这样说,让所有控制器都继承一个BaseController不就可以了吗?我在这里要解释一下这样做的缺点:假如你的项目里有许多Controller的话,你就需要把项目里凡是没有继承自BaseController的每个Controller都做一次修改了,而且随意更改层级结构会发生意想不到的错误。
其实我们的目的就是重写ViewDidLoad的方法,并在他的方法最后加上几句Log,所以我们需要给UIViewController建立一个category,因为我们知道,如果在Catagory中重写一个方法,就会覆盖它的原有方法实现,但是,这样做以后就没有办法调用系统原有的方法,因为在一个方法里调用自己的方法会是一个死循环。所以我们的解决办法就是,另外写一个方法来和viewDidLoad“交换”,这样外部调用viewDidLoad就会调到新建的这个方法中,同样,我们调用新建的方法就会调用到系统的viewDidLoad中了。
代码:
+(void)load{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//获取到这个累的viewDidLoad方法,他的累心是一个object_method结构体的指针
Method viewDidLoad = class_getInstanceMethod(self, @selector(viewDidLoad));
//获取自己刚刚新建的方法
Method viewDidLoaded = class_getInstanceMethod(self, @selector(viewDidLoaded));
method_exchangeImplementations(viewDidLoad, viewDidLoaded);
});
}
//新建一个方法与viewDidLoad交换
-(void)viewDidLoaded{
[self viewDidLoaded];
NSLog(@"cuihongbao");
}
如果对Runtime有一定了解的话,一定听说过或者用过这个函数:
1 | void method_exchangeImplementations(Method m1, Method m2) |
我们的程序中有许多个ViewController,我想在对项目改动最小的情况下,在当每个Controller执行完ViewDidLoad以后就在控制台把自己的名字打印出来,方便我去做调试或者了解项目结构。
有许多朋友会这样说,让所有控制器都继承一个BaseController不就可以了吗?我在这里要解释一下这样做的缺点:假如你的项目里有许多Controller的话,你就需要把项目里凡是没有继承自BaseController的每个Controller都做一次修改了,而且随意更改层级结构会发生意想不到的错误。
其实我们的目的就是重写ViewDidLoad的方法,并在他的方法最后加上几句Log,所以我们需要给UIViewController建立一个category,因为我们知道,如果在Catagory中重写一个方法,就会覆盖它的原有方法实现,但是,这样做以后就没有办法调用系统原有的方法,因为在一个方法里调用自己的方法会是一个死循环。所以我们的解决办法就是,另外写一个方法来和viewDidLoad“交换”,这样外部调用viewDidLoad就会调到新建的这个方法中,同样,我们调用新建的方法就会调用到系统的viewDidLoad中了。
代码:
+(void)load{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//获取到这个累的viewDidLoad方法,他的累心是一个object_method结构体的指针
Method viewDidLoad = class_getInstanceMethod(self, @selector(viewDidLoad));
//获取自己刚刚新建的方法
Method viewDidLoaded = class_getInstanceMethod(self, @selector(viewDidLoaded));
method_exchangeImplementations(viewDidLoad, viewDidLoaded);
});
}
//新建一个方法与viewDidLoad交换
-(void)viewDidLoaded{
[self viewDidLoaded];
NSLog(@"cuihongbao");
}
相关文章推荐
- iOS运行时与method swizzling
- iOS运行时与method swizzling
- [ios]CGContext 函数说明
- [ios]presentModalViewController和dismissModalViewControllerAnimated汇总
- iOS-正则表达式的使用
- iOS--串口通讯初始化
- 【转载】Xcode 4.1~4.6 + iOS 5、iOS 6免证书(iDP)开发+真机调试+生成IPA全攻略
- 如何让iOS应用程序访问到 dev下的设备
- ios6.0横竖屏切换问题解决
- 2011年冬季最新斯坦福大学公开课:iOS程序开发教程【中文字幕】
- ios和配件进行通讯[转]
- ios开发 获取系统时间
- iOS 常用代码汇总(持续更新)
- iOS开发实例-七杯茶奶茶点餐系统
- iOS 编译百度地图静态库-合二为一
- iOS-coverFlow效果简单实现
- iOS home键直接退出
- iOS单例模式使用
- 截取部分图片并显示-ios例子[转载]
- 关于IOS获取本地通讯录信息(包含iOS9.0前后)