class_getInstanceMethod和class_getClassMethod的区别

转载自:https://blog.csdn.net/baidu_25743639/article/details/51793764

 

今天在学习runtime的method_exchangeImplementations进行方法交换的时候,将class_getInstanceMethod方法误写成class_getClassMethod,结果发现方法交换失败,

找了好久发现在获取方法的时候写错了;

先简单介绍下这两个方法是干什么用的:

 

class_getInstanceMethod      得到类的实例方法

 

class_getClassMethod          得到类的类方法 

从官方文档中我们可以看到:

 

 
  1. /**

  2. * Returns a specified instance method for a given class.

  3. *

  4. * @param cls The class you want to inspect.

  5. * @param name The selector of the method you want to retrieve.

  6. *

  7. * @return The method that corresponds to the implementation of the selector specified by

  8. * \e name for the class specified by \e cls, or \c NULL if the specified class or its

  9. * superclasses do not contain an instance method with the specified selector.

  10. *

  11. * @note This function searches superclasses for implementations, whereas \c class_copyMethodList does not.

  12. */

  13. OBJC_EXPORT Method class_getInstanceMethod(Class cls, SEL name)

  14. __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);

  15.  
  16. /**

  17. * Returns a pointer to the data structure describing a given class method for a given class.

  18. *

  19. * @param cls A pointer to a class definition. Pass the class that contains the method you want to retrieve.

  20. * @param name A pointer of type \c SEL. Pass the selector of the method you want to retrieve.

  21. *

  22. * @return A pointer to the \c Method data structure that corresponds to the implementation of the

  23. * selector specified by aSelector for the class specified by aClass, or NULL if the specified

  24. * class or its superclasses do not contain an instance method with the specified selector.

  25. *

  26. * @note Note that this function searches superclasses for implementations,

  27. * whereas \c class_copyMethodList does not.

  28. */

  29. OBJC_EXPORT Method class_getClassMethod(Class cls, SEL name)

  30. __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);

好了废话不多说,上代码来说明一下:

 

DEMO:

测试所用的Person类:

 

 
  1. #import <Foundation/Foundation.h>

  2.  
  3. @interface Person : NSObject

  4.  
  5. @property(nonatomic, assign) NSInteger age;

  6. @property(nonatomic, copy) NSString * name;

  7.  
  8. +(Person *)sharedManager;

  9.  
  10. - (instancetype)init;

  11.  
  12. + (void) printDZ;

  13.  
  14. - (void) printDZL;

  15.  
  16. @end

  17.  
  18.  
  19.  
  20. #import "Person.h"

  21.  
  22. @interface Person ()

  23.  
  24. @property(nonatomic, strong) NSString * sex;

  25.  
  26. @end

  27.  
  28. @implementation Person

  29.  
  30.  
  31. +(Person *)sharedManager

  32. {

  33.     static Person *sharedManager;

  34.     static dispatch_once_t onceTest;

  35.     dispatch_once(&onceTest, ^{

  36.         sharedManager = [[Person alloc] init];

  37.     });

  38.     NSLog(@"+ method");

  39.     return sharedManager;

  40. }

  41.  
  42.  
  43. - (instancetype)init

  44. {

  45.     self = [super init];

  46.     if (self) {

  47.         self = [super init];

  48.         self.sex = @"-----------";

  49.         self.age = 19;

  50.         self.name = @"sb";

  51.     }

  52.     return self;

  53. }

  54.  
  55. + (void)printDZ

  56. {

  57.     NSLog(@"this is a class method");

  58. }

  59.  
  60. - (void)printDZL

  61. {

  62.     NSLog(@"this is a instance method");

  63. }

  64.  
  65. @end

  66.  
  67.  

测试Demo:

 

 

 
  1. - (void)viewDidLoad {

  2. [super viewDidLoad];

  3. // Do any additional setup after loading the view, typically from a nib.

  4.  
  5. Person * p1 = [[Person alloc] init];

  6.  
  7. Method m1 = class_getInstanceMethod([p1 class], @selector(printDZL));

  8. Method m2 = class_getClassMethod([Person class], @selector(printDZ));

  9.     NSLog(@"测试前:");

  10.     [p1 printDZL];

  11.     [Person printDZ];

  12.     method_exchangeImplementations(m1, m2);

  13.     NSLog(@"测试后:");

  14.     [p1 printDZL];

  15.     [Person printDZ];

  16.  
  17. }


输出:

 

 

 
  1. 2016-06-30 22:37:08.539 02-runtime[2776:69899] 测试前:

  2. 2016-06-30 22:37:08.539 02-runtime[2776:69899] this is a instance method

  3. 2016-06-30 22:37:08.539 02-runtime[2776:69899] this is a class method

  4. 2016-06-30 22:37:08.540 02-runtime[2776:69899] 测试后:

  5. 2016-06-30 22:37:08.540 02-runtime[2776:69899] this is a class method

  6. 2016-06-30 22:37:08.540 02-runtime[2776:69899] this is a instance method


 

 

 

由输出可见,方法体交换了,说明class_getInstanceMethod成功得到了实例方法,class_getClassMethod成功得到了类方法

但是当用class_getInstanceMethod来取类方法,用class_getClassMethod来取实例方法时:

 
  1. - (void)viewDidLoad {

  2. [super viewDidLoad];

  3. // Do any additional setup after loading the view, typically from a nib.

  4.  
  5. Person * p1 = [[Person alloc] init];

  6.  
  7. // Method m1 = class_getInstanceMethod([p1 class], @selector(printDZL));

  8. // Method m2 = class_getClassMethod([Person class], @selector(printDZ));

  9. Method m1 = class_getInstanceMethod([Person class], @selector(printDZ));

  10. Method m2 = class_getClassMethod([p1 class], @selector(printDZL));

  11. NSLog(@"测试前:");

  12. [p1 printDZL];

  13. [Person printDZ];

  14. method_exchangeImplementations(m1, m2);

  15. NSLog(@"测试后:");

  16. [p1 printDZL];

  17. [Person printDZ];

  18. }

输出:

 

 
  1. 2016-06-30 22:38:10.050 02-runtime[2793:70426] 测试前:

  2. 2016-06-30 22:38:10.051 02-runtime[2793:70426] this is a instance method

  3. 2016-06-30 22:38:10.051 02-runtime[2793:70426] this is a class method

  4. 2016-06-30 22:38:10.051 02-runtime[2793:70426] 测试后:

  5. 2016-06-30 22:38:10.051 02-runtime[2793:70426] this is a instance method

  6. 2016-06-30 22:38:10.051 02-runtime[2793:70426] this is a class method


由输出可见,没有发生交换,可知这样是取不到的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值