美文网首页
Runtime 方法

Runtime 方法

作者: docallsama | 来源:发表于2017-12-04 15:39 被阅读3次

    各种方法

    1. class_addMethod 向类添加方法

    添加方法需要的参数:类,方法名称,类中实现的方法,方法的属性

    关于方法属性的参数:每个方法必须有至少两个参数- self 和 _cmd,则第一个字符为方法返回类型,第二、三个字符为"@"和":"。

    方法添加成功之后再次添加就会返回false,这时候如果需要替换方法,只需要exchangeImplement即可。

    更多方法类型参考链接
    NSHipster中的介绍

    - (void)addMethodForCar {
        Class carClass = objc_getClass("Car");
        BOOL isSuccess = class_addMethod(carClass, @selector(reverse), class_getMethodImplementation([self class], @selector(controllerReverse)), "v@:");
        
        if (isSuccess) {
            Car *fit = [[Car alloc] init];
            [fit performSelector:@selector(reverse) withObject:nil];
        }
    }
    
    //添加的方法实现
    - (void)controllerReverse {
        NSLog(@"car reverse");
    }
    
    1. class_copyMethodList 获取类声明方法
      category添加的方法也会在类的methodlist中出现,按照编译顺序category添加的方法会在类原本方法的前面。
    //获取实体方法
    unsigned int outcountMethod;
    id PersonClass = objc_getClass("Car");
    Method *methods = class_copyMethodList(PersonClass, &outcountMethod);
    for (int i = 0; i < outcountMethod; i++) {
        Method method = methods[i];
        SEL methodSEL = method_getName(method);
        const char *selName = sel_getName(methodSEL);
        
        if (methodSEL) {
            NSLog(@"selector name -> %s",selName);
        }
    }
    free(methods);
    
    // console output:
    // selector name -> fakeRun
    // selector name -> normalRun  iOSInterviewProblems`-[Person(MethodRun) normalRun] at Person+MethodRun.m:17
    // selector name -> normalRun  iOSInterviewProblems`-[Person normalRun] at Person.m:40
    
    1. class_replaceMethod 替换已有的方法
    Class PersonClass = objc_getClass("Person");
    //声明替换的方法
    IMP replaceIMP = class_getMethodImplementation([self class], @selector(playFootBall:));
    //替换掉原有方法 
    class_replaceMethod(PersonClass, @selector(innerMethod), replaceIMP, "v@:");
    
    id person = [[PersonClass alloc] init];
    [person performSelector:@selector(innerMethod) withObject:@"allen"];
    
    // console output:
    // allen is playing football
    
    1. method_exchangeImplementations 替换方法实现
    //使用已有方法替换方法
    Class PersonClass = objc_getClass("Person");
    Method originalMethod = class_getInstanceMethod(PersonClass, @selector(originalMethodRun));
    Method swizzledMethod = class_getInstanceMethod(PersonClass, @selector(swizzledMethodRun));
    method_exchangeImplementations(originalMethod, swizzledMethod);
        
    id person = [[PersonClass alloc] init];
    [person performSelector:@selector(originalMethodRun) withObject:nil];
    
    // console output:
    // perform swizzled method run
    

    参考代码 github链接

    相关文章

      网友评论

          本文标题:Runtime 方法

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