二.方法
1.Dynamically Adding a Method
Class c = [NSObject class];
IMP greetingIMP = imp_implementationWithBlock((NSString *)^(id self, NSString * name){
return [NSString stringWithFormat:@"Hello, %@!", name];
});
const char *greetingTypes = [[NSString stringWithFormat:@"%s%s%s", @encode(id), @encode(id), @encode(SEL)] UTF8String];
class_addMethod(c, @selector(greetingWithName:), greetingIMP, greetingTypes);
2.Exchange Method
//同一个对象交换方法的实现部分。eat和drink互换实现部分
Method eat = class_getInstanceMethod([Person class], sel_registerName("eat:"));
Method drink = class_getInstanceMethod([Person class], sel_registerName("drink:"));
method_exchangeImplementations(eat, drink);
//替换方法的实现部分。eat被替换成play
Method play = class_getInstanceMethod([Student class], sel_registerName("play:"));
class_replaceMethod([Person class], sel_registerName("eat:"), method_getImplementation(play), "v@:");
Person *per = [[Person alloc]init];
[per eat:@"超级汉堡"];
[per drink:@"焦糖咖啡"];
3.Method Swizzling
#import "UIViewController+Hook.h"
#import <objc/message.h>
@implementation UIViewController (Hook)
//1.load和initialize有什么区别?
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originSel = @selector(viewWillAppear:);
SEL swizzSel = @selector(swizz_viewWillAppear:);
Method originMethod = class_getInstanceMethod(class, originSel);
Method swizzMethod = class_getInstanceMethod(class, swizzSel);
/*2.为什么要用addMethod,为什么不直接调用methodExchange呢??
@note class_addMethod will add an override of a superclass's implementation,
but will not replace an existing implementation in this class.
To change an existing implementation, use method_setImplementation.
*/
BOOL didAdded = class_addMethod(class, originSel, method_getImplementation(swizzMethod), method_getTypeEncoding(swizzMethod));
if (didAdded) {
class_replaceMethod(class,swizzSel, method_getImplementation(originMethod), method_getTypeEncoding(originMethod));
}else {
method_exchangeImplementations(originMethod, swizzMethod);
}
});
}
- (void)swizz_viewWillAppear:(BOOL)animated {
[self swizz_viewWillAppear:animated];
NSLog(@"%@ -- appear ",NSStringFromClass([self class]));
}
@end
网友评论