Runtime 常用的 API
1 - 类
② 成员变量
③ 属性
④ 方法
⑤ 其他
2 - 如何使用
① 新建 Person 和 Animal 两个类,如下
② 代码示例
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 #import "Animal.h" 4 #import <objc/runtime.h> 5 6 void run(id self, SEL _cmd){ 7 8 NSLog(@"___%@ - %@", self, NSStringFromSelector(_cmd)); 9 } 10 11 // 成员变量 12 int main(int argc, const char * argv[]) { 13 14 // 获取成员变量信息 15 Ivar ageIvar = class_getInstanceVariable([Person class], "_age"); 16 17 // 注意返回的时 C语言 字符串 18 NSLog(@"%s %s", ivar_getName(ageIvar), ivar_getTypeEncoding(ageIvar)); // _age i 19 20 // 设置和获取成员变量的值 21 Ivar nameIvar = class_getInstanceVariable([Person class], "_name"); 22 23 // 给成员变量赋值 24 Person *person = [[Person alloc] init]; 25 object_setIvar(person, nameIvar, @"abc"); 26 object_setIvar(person, ageIvar, (__bridge id)(void *)100); // 整型不能直接赋值 27 NSLog(@"%@ %d", person.name, person.age);// abc 100 28 29 // 成员变量的数量 30 unsigned int count; 31 // 第二个参数需要传进一个整型地址,其函数内部返回一个值用来记录成员变量数量 32 Ivar *ivars = class_copyIvarList([Person class], &count); 33 34 NSLog(@"%d",count); // 2 35 36 // 遍历成员变量 37 for (int i = 0; i < count; i++) { 38 Ivar ivar = ivars[i]; 39 NSLog(@"%s %s", ivar_getName(ivar), ivar_getTypeEncoding(ivar)); 40 // i = 0 时 _age i 41 // i = 1 时 _name @"NSString" 42 } 43 44 // 需要释放 45 free(ivars); 46 47 return 0; 48 } 49 50 51 52 // 类 53 void testONE(){ 54 55 Person *pe1 = [Person new]; 56 Animal *an1 = [Animal new]; 57 58 // 设置 isa 指向的 Class 59 object_setClass(pe1, [Animal class]); 60 61 // 获取 isa 指向的 Class 62 NSLog(@"%@",object_getClass(pe1)); // Animal 类对象 63 [pe1 runAway]; // <Animal: 0x10040d690> runAway ! 64 65 NSLog(@"%@",object_getClass([Person class]));// Person 元类 66 NSLog(@"%@",object_getClass(object_getClass([Person class]))); // 根类 NSObject 67 68 // 判断是不是一个 Class 69 NSLog(@"%d %d %d",object_isClass(an1),object_isClass([Animal class]),object_isClass(object_getClass([Person class]))); 70 // 0 1 1 71 72 } 73 74 // 方法 75 void testTWO(){ 76 77 // 创建一个新的类 78 Class NewClass = objc_allocateClassPair([NSObject class], "God", 0); 79 80 // 添加成员变量(Class, 成员变量, 内存大小, 内存对齐, 数据类型的encode编码) 81 // 注意:添加成员变量必须在类注册之前完成 82 class_addIvar(NewClass, "_age", 4, 1, @encode(int)); 83 class_addIvar(NewClass, "_weight", 4, 1, "i"); // i 就是 int 的 encode编码 84 85 // 新类创建后需要注册 86 objc_registerClassPair(NewClass); 87 88 // 添加方法:可以在类注册之后完成 89 class_addMethod(NewClass, @selector(run), (IMP)run, "v@:"); 90 91 id erlang = [NewClass new]; 92 93 [erlang setValue:@10 forKey:@"_age"]; 94 [erlang setValue:@20 forKey:@"_weight"]; 95 [erlang run]; 96 97 // 将 erlang 销毁 98 erlang = nil; 99 100 NSLog(@"%@ %@", [erlang valueForKey:@"_age"], [erlang valueForKey:@"_weight"]); 101 102 // 在不需要这个类时释放:如果前面 erlang 没有置空(销毁),执行此行代码则程序 Crash 103 objc_disposeClassPair(NewClass);// 执行此函数前,它不允许前面还有该类的实例,否则 crash 104 105 }
标签:erlang,ivar,NSLog,object,iOS,Person,API,Runtime,class From: https://www.cnblogs.com/self-epoch/p/17239482.html