认识两个家伙:
class_getInstanceMethod 得到类的实例方法
class_getClassMethod 得到类的类方法
官方介绍:
/**
* Returns a specified instance method for a given class.
*
* @param cls The class you want to inspect.
* @param name The selector of the method you want to retrieve.
*
* @return The method that corresponds to the implementation of the selector specified by
* \e name for the class specified by \e cls, or \c NULL if the specified class or its
* superclasses do not contain an instance method with the specified selector.
*
* @note This function searches superclasses for implementations, whereas \c class_copyMethodList does not.
*/
OBJC_EXPORT Method class_getInstanceMethod(Class cls, SEL name)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/**
* Returns a pointer to the data structure describing a given class method for a given class.
*
* @param cls A pointer to a class definition. Pass the class that contains the method you want to retrieve.
* @param name A pointer of type \c SEL. Pass the selector of the method you want to retrieve.
*
* @return A pointer to the \c Method data structure that corresponds to the implementation of the
* selector specified by aSelector for the class specified by aClass, or NULL if the specified
* class or its superclasses do not contain an instance method with the specified selector.
*
* @note Note that this function searches superclasses for implementations,
* whereas \c class_copyMethodList does not.
*/
OBJC_EXPORT Method class_getClassMethod(Class cls, SEL name)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
开始实践:
Person类:
Person.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Person : NSObject
@property (nonatomic,assign) NSInteger age;
@property (nonatomic,copy) NSString *name;
+(void)printDZ;
-(void)printDZL;
@end
NS_ASSUME_NONNULL_END
Person.m
#import "Person.h"
@interface Person()
@property(nonatomic,strong) NSString *sex;
@end
@implementation Person
/// class method
+(void)printDZ {
NSLog(@"this is a class method");
}
/// instacnce method
-(void)printDZL {
NSLog(@"this is a instance method");
}
@end
测试控制器ViewController:
Person *p1 = [[Person alloc] init];
Method m1 = class_getInstanceMethod([p1 class], @selector(printDZL));
Method m2 = class_getClassMethod([Person class], @selector(printDZ));
NSLog(@"测试前");
[p1 printDZL];
[Person printDZ];
method_exchangeImplementations(m1, m2);
NSLog(@"测试后");
[p1 printDZL];
[Person printDZ];
输出:
2019-04-19 08:56:57.538723+0800 TestSwizDemo[1268:31931] 测试前
2019-04-19 08:56:57.538881+0800 TestSwizDemo[1268:31931] this is a instance method
2019-04-19 08:56:57.538958+0800 TestSwizDemo[1268:31931] this is a class method
2019-04-19 08:56:57.539793+0800 TestSwizDemo[1268:31931] 测试后
2019-04-19 08:56:57.539907+0800 TestSwizDemo[1268:31931] this is a class method
2019-04-19 08:56:57.540013+0800 TestSwizDemo[1268:31931] this is a instance method
由输出可见,方法体交换了,说明class_getInstanceMethod成功得到了实例方法,class_getClassMethod成功得到了类方法
但是当用class_getInstanceMethod来取类方法,用class_getClassMethod来取实例方法时:
Person * p1 = [[Person alloc] init];
// Method m1 = class_getInstanceMethod([p1 class], @selector(printDZL));
// Method m2 = class_getClassMethod([Person class], @selector(printDZ));
Method m1 = class_getInstanceMethod([Person class], @selector(printDZ));
Method m2 = class_getClassMethod([p1 class], @selector(printDZL));
NSLog(@"测试前:");
[p1 printDZL];
[Person printDZ];
method_exchangeImplementations(m1, m2);
NSLog(@"测试后:");
[p1 printDZL];
[Person printDZ];
输出:
2019-04-19 09:05:34.968824+0800 TestSwizDemo[1350:37896] 测试前
2019-04-19 09:05:34.968940+0800 TestSwizDemo[1350:37896] this is a instance method
2019-04-19 09:05:34.969006+0800 TestSwizDemo[1350:37896] this is a class method
2019-04-19 09:05:34.969090+0800 TestSwizDemo[1350:37896] 测试后
2019-04-19 09:05:34.969158+0800 TestSwizDemo[1350:37896] this is a instance method
2019-04-19 09:05:34.969216+0800 TestSwizDemo[1350:37896] this is a class method
由输出可见,没有发生交换,可知这样是取不到的。
参考链接:
https://blog.csdn.net/baidu_25743639/article/details/51793764
网友评论