Runtime 方法

各种方法

  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链接

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 5,922评论 0 9
  • 收 集 文 章 / 超 人文章出处 Rumtime方法说明 获取类的类名 获取类的父类 class_getSup...
    树下敲代码的超人阅读 4,198评论 0 13
  • 本篇文章在《iOS开发之Runtime常用示例总结》基础上修改,地址是「:」http://www.cocoachi...
    小__小阅读 5,837评论 1 3
  • 前言 runtime其实在我们日常开发过程中很少使用到,尤其是像我现在比较初级的程序猿就更用不到了。但是去面试很多...
    WolfTin阅读 4,145评论 0 2
  • 我们很久都没有联系了 你曾说 不联系不代表已忘记 只是找不到主动的理由 你还说 朋友终究留在那 不增不减 唯独好久...
    安嫚儿阅读 3,826评论 1 7

友情链接更多精彩内容