美文网首页
runtime(2)--method

runtime(2)--method

作者: 初灬终 | 来源:发表于2018-11-26 19:27 被阅读4次

二.方法

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

相关文章

网友评论

      本文标题:runtime(2)--method

      本文链接:https://www.haomeiwen.com/subject/hoxgxqtx.html