1.实例方法交换
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method origleMe = class_getInstanceMethod([self class], @selector(viewWillAppear:)); // 如果子类没有实现 这个获取到的是superClass的方法
Method newMe = class_getInstanceMethod([self class], @selector(my_viewWillAppear:));
// 这个方法 往类里面添加 方法
//1.如果类没有实现这个方法,class_addMethod给类添加一个方法,方法的选择器还是它本身,方法的实现和参数类型都是要替换的新的方法,这种情况返回的bool是YES,在调用class_replaceMethod替换新增的方法的实现为继承的superclass的方法实现,
// 疑问1 class_addMethod 如果添加成功,添加的方法的实现其实是新增的方法的实现,class_replaceMethod 替换的时候获取方法IMP时候应该用最开始获取的method,如果不这样有可能用,再次获取Method那么class_replaceMethod替换的还是新增的方法,相当于系统的和新的方法的实现都是新增的实现 验证 正确 ,如果这样写 会循环调用
//2.如果类里面以及有这个方法,class_addMethod添加失败,直接交换两个方法的实现即可
BOOL isSuccess = class_addMethod([self class], @selector(viewWillAppear:), method_getImplementation(newMe), method_getTypeEncoding(newMe));
// 测试 疑问1
// Method aOrigleMe = class_getInstanceMethod([self class], @selector(viewWillAppear:));
if (isSuccess) {
class_replaceMethod([self class], method_getName(newMe), method_getImplementation(origleMe), method_getTypeEncoding(origleMe));
// 测试 疑问1
// class_replaceMethod([self class], method_getName(newMe), method_getImplementation(aOrigleMe), method_getTypeEncoding(aOrigleMe));
} else {
method_exchangeImplementations(origleMe, newMe);
}
});
}
- (void)my_viewWillAppear:(BOOL)animated
{
[self my_viewWillAppear:animated];
// [self viewWillAppear:animated];
NSLog(@"%s",__func__);
}
2.类方法交换
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 这个应为要获取类方法,所以需要获取到元类对象
// 因为实例方法存放在类对象里面,类方法存放在元类对象里面
Class aClass = object_getClass(self);
SEL orgiSel = @selector(testOrgiClassMethod);
SEL newSel = @selector(testNewClassMethod);
Method oriClassMe = class_getClassMethod(aClass, orgiSel);
Method newClassMe = class_getClassMethod(aClass, newSel);
BOOL isSuccess = class_addMethod(aClass, orgiSel, method_getImplementation(newClassMe), method_getTypeEncoding(newClassMe));
if (isSuccess) {
class_replaceMethod(aClass, newSel, method_getImplementation(oriClassMe), method_getTypeEncoding(oriClassMe));
} else {
method_exchangeImplementations(oriClassMe, newClassMe);
}
});
}
+ (void)testOrgiClassMethod
{
NSLog(@"%s",__func__);
}
+ (void)testNewClassMethod
{
NSLog(@"%s",__func__);
}
3.class一点总结
// +(Class)class{return self} -(Class)class{return object_getClass(self)}
/*
实例对象
1. -(Class)class; 获取到类对象
2. object_getClass(self); 获取到类对象
3. object_getClass([self class]); 获取元类
类对象
1.+(Class)class; 获取到还是本身
2.object_getClass(self); 获取到元类对象
3.object_getClass([self class]); 获取元类对象
// 为神魔 在一个类里面 [self class] == [super class];
应为oc的方法调用都会是转成消息
[self class] 会调用 objc_msgSend(self,@selecter(class));
[super class] 会调用 objc_msgSendSuper(struct objc_super *super, SEL)
// 这个结构体里面的 receiver 就是self 调用super时他会从父类开始查找class的方法,但是消息的接受者还是 self ,所以打印的它俩相同
struct objc_super {
Specifies an instance of a class.
__unsafe_unretained id receiver;
Specifies the particular superclass of the instance to message.
#if !defined(__cplusplus) && !__OBJC2__
For compatibility with old objc-runtime.h header
__unsafe_unretained Class class;
#else
__unsafe_unretained Class super_class;
#endif
super_class is the first class to search
};
// 发消息,系统会自动从下面几个中间挑选合适的调用
objc_msgSend objc_msgSend_stret objc_msgSendSuper objc_msgSendSuper_stret
* @note When it encounters a method call, the compiler generates a call to one of the
* functions \c objc_msgSend, \c objc_msgSend_stret, \c objc_msgSendSuper, or \c objc_msgSendSuper_stret.
* Messages sent to an object’s superclass (using the \c super keyword) are sent using \c objc_msgSendSuper;
* other messages are sent using \c objc_msgSend. Methods that have data structures as return values
* are sent using \c objc_msgSendSuper_stret and \c objc_msgSend_stret.
*/
项目地址:https://github.com/hkkh/iOS-Swizzle-Method.git
网友评论