iOS利用runtime追踪对象的每一个方法
2017-01-19 11:28
375 查看
iOS利用runtime追踪对象的每一个方法
我们会用到runtime替换方法来监听某个方法的调用。例如,项目中每个Controller都直接继承了UIViewController,但是现在想监听每个Controller的viewDidAppear 和 viewDidDisappear,用法如下:void qhd_exchangeInstanceMethod(Class class, SEL originalSelector, SEL newSelector) { Method originalMethod = class_getInstanceMethod(class, originalSelector); Method newMethod = class_getInstanceMethod(class, newSelector); if(class_addMethod(class, originalSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) { class_replaceMethod(class, newSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, newMethod); } } @implementation UIViewController (Test) + (void)load { qhd_exchangeInstanceMethod([self class], @selector(viewDidAppear:), @selector(qhd_viewDidAppear:)); qhd_exchangeInstanceMethod([self class], @selector(viewDidDisappear:), @selector(qhd_viewDidDisappear:)); } - (void)qhd_viewDidAppear:(BOOL)animated { //[MobClick beginLogPageView:self.title]; [self qhd_viewDidAppear:animated]; } - (void)qhd_viewDidDisappear:(BOOL)animated { //[MobClick endLogPageView:self.title]; [self qhd_viewDidDisappear:animated]; } @end
最近产生了一个的想法:替换一个类的所有方法,每一个方法都打印一个log,看看调用顺序是怎样的,例如我想知道UIViewController在运行时到底都调用了哪些方法,包括私有方法。
思路是这样的:
1.通过class_copyMethodList得出一个类的所有方法。
2.通过method_getTypeEncoding和method_copyReturnType得出方法的参数类型和返回值。
3.创建出SEL和IMP,通过class_addMethod动态添加新方法。
4.通过交换的思想,在新方法里通过NSInvocation来调用原方法。
难点在于,新方法里面怎么把方法的“实现”(即IMP)绑定上,并且在“实现”里调用原方法。在runtime的头文件中Method的结构:
typedef struct objc_method *Method; struct objc_method { SEL method_name char *method_types IMP method_imp }
可以看到Method包含了是三个元素:一个SEL,一个char *,一个IMP。
SEL是方法名,char *是方法的类型,IMP就是实现的地址。
具体代码查看github:https://github.com/qhd/ANYMethodLog.git
相关文章推荐
- 利用runtime追踪对象的每一个方法
- 【iOS开发-117】block为什么用copy?利用runtime运行时的objc_方法为分类扩充成员变量
- iOS Runtime应用小例子 不引入类怎么创建这个类的对象和执行类的方法
- iOS runtime方法详解之对象关联
- ios 中调用函数的方法是消息传递,这个和普通的函数调用的区别是,你可以随时对一个对象传递任何消息,而不需要在编译的时候声明这些方法。所以Objective-C可以在runtime的时候
- ios 利用runtime 机制 交换系统内部方法的实现
- iOS 利用runtime调用方法
- iOS 利用runtime关联对象
- 地址方法[ios开发]利用有道翻译API实现简单的翻译功能地址方法
- Javascript 的函数式对象(一)利用闭包模拟类的私有变量和方法
- Javascript 的函数式对象(三)利用闭包模拟类的静态变量和方法
- 利用Java的反射机制解析一个Class对象的详细内容(工具方法留用)
- iOS崩溃日志crash logs追踪以及调试方法
- IOS UISplitViewController之 解决 密码框添加之后 调用子视图的转向方法之时 对象为空
- javascript:利用Object.create()方法创建对象
- iOS上的safrai不支持使用关键字作为对象属性名称或方法名称
- IOS 笔记 - 利用UIImage的stretchableImageWithLeftCapWidth方法给UIButton设置背景
- 在 iOS 或者 Mac OS X 中将 NSDictionary 映射为本地对象的方法
- 在 iOS 或者 Mac OS X 中将 NSDictionary 映射为本地对象的方法
- ios高阶教程 块对象(block)的利用