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

  1. #import "NSArray+Swizzle.h"  
  2.   
  3.   
  4. @implementation NSArray (Swizzle)  
  5.   
  6.   
  7. - (id)myLastObject  
  8. {  
  9.     id ret = [self myLastObject];  
  10.     NSLog(@"**********  myLastObject *********** ");  
  11.     return ret;  
  12. }  
  13. @end  


乍一看,这不递归了么?别忘记这是我们准备调换IMP的selector,[self myLastObject] 将会执行真的 [self lastObject] 。



第二步:调换IMP

  1. #import <objc/runtime.h>  
  2. #import "NSArray+Swizzle.h"  
  3.   
  4.   
  5. int main(int argc, char *argv[])  
  6. {  
  7.     @autoreleasepool {  
  8.           
  9.         Method ori_Method =  class_getInstanceMethod([NSArray class], @selector(lastObject));  
  10.         Method my_Method = class_getInstanceMethod([NSArray class], @selector(myLastObject));  
  11.         method_exchangeImplementations(ori_Method, my_Method);  
  12.           
  13.         NSArray *array = @[@"0",@"1",@"2",@"3"];  
  14.         NSString *string = [array lastObject];  
  15.         NSLog(@"TEST RESULT : %@",string);  
  16.           
  17.         return 0;  
  18.     }  
  19. }  



控制台输出Log:

  1. 2013-07-18 16:26:12.585 Hook[1740:c07] **********  myLastObject ***********   
  2. 2013-07-18 16:26:12.589 Hook[1740:c07] TEST RESULT : 3  



原文链接:http://blog.csdn.net/yiyaaixuexi/article/details/9374411

posted on 2015-04-14 17:45  醉衡  阅读(271)  评论(0)    收藏  举报

导航