Objective-C: Method Swizzling<转自CSDN>
Objective-C的hook方案(一): Method Swizzling
在没有一个类的实现源码的情况下,想改变其中一个方法的实现,除了继承它重写、和借助类别重名方法暴力抢先之外,还有更加灵活的方法吗?在Objective-C编程中,如何实现hook呢?标题有点大,计划分几篇来总结。
本文主要介绍针对selector的hook,主角被标题剧透了———— Method Swizzling 。
我们可以利用 method_exchangeImplementations 来交换2个方法中的IMP,
我们可以利用 class_replaceMethod 来修改类,
我们可以利用 method_setImplementation 来直接设置某个方法的IMP,
……
归根结底,都是偷换了selector的IMP,如下图所示:
举个例子好了,我想钩一下NSArray的lastObject 方法,只需两个步骤。
第一步:给NSArray加一个我自己的lastObject
- #import "NSArray+Swizzle.h"
- @implementation NSArray (Swizzle)
- - (id)myLastObject
- {
- id ret = [self myLastObject];
- NSLog(@"********** myLastObject *********** ");
- return ret;
- }
- @end
乍一看,这不递归了么?别忘记这是我们准备调换IMP的selector,[self myLastObject] 将会执行真的 [self lastObject] 。
第二步:调换IMP
- #import <objc/runtime.h>
- #import "NSArray+Swizzle.h"
- int main(int argc, char *argv[])
- {
- @autoreleasepool {
- Method ori_Method = class_getInstanceMethod([NSArray class], @selector(lastObject));
- Method my_Method = class_getInstanceMethod([NSArray class], @selector(myLastObject));
- method_exchangeImplementations(ori_Method, my_Method);
- NSArray *array = @[@"0",@"1",@"2",@"3"];
- NSString *string = [array lastObject];
- NSLog(@"TEST RESULT : %@",string);
- return 0;
- }
- }
控制台输出Log:
- 2013-07-18 16:26:12.585 Hook[1740:c07] ********** myLastObject ***********
- 2013-07-18 16:26:12.589 Hook[1740:c07] TEST RESULT : 3
原文链接:http://blog.csdn.net/yiyaaixuexi/article/details/9374411
浙公网安备 33010602011771号