第一次看到runtime时,觉得太高大上,动态获取方法、属性等简直厉害的不要不要的。在经过查找资料+实践后,发现runtime并没有想象中那么复杂,接下来对runtime进行基本的介绍。
要使用运行时方法需要引入runtime.h文件
一、基础知识
Method :成员方法
Ivar : 成员变量
二、常用方法
class_copyPropertyList : 获取属性列表
class_copyMethodList : 获取成员方法列表
class_copyIvarList:获取成员变量列表
ivar_getName:获取变量名
property_getName:获取属性名
使用示例:
1.获取成员变量列表
//1.获取变量list unsigned int ivarCount = 0; //成员变量数 Ivar *ivarList = class_copyIvarList([self class], &ivarCount);//ivar数组 for (int i = 0; i < ivarCount; i++) {//遍历 Ivar ivar = ivarList[i]; //获取ivar const char *name = ivar_getName(ivar);//获取变量名 NSString *key = [NSString stringWithUTF8String:name]; NSLog(@"%@", key); }
free(ivarList);
2.获取属性列表
unsigned int count = 0; objc_property_t *propertList = class_copyPropertyList([self class], &count); for (int i = 0; i < count; i++) { objc_property_t property = propertList[i]; const char *name = property_getName(property); const char *attrs = property_getAttributes(property); // property_copyAttributeValue(,) 第一个参数为objc_property_t,第二个参数"V"获取变量名,"T"获取类型 const char *value = property_copyAttributeValue(property, "V"); NSLog(@"name = %s, attrs = %s, value = %s", name, attrs, value); }
free(propertList);
3.获取方法列表
unsigned int count = 0; Method *methodList = class_copyMethodList([self class], &count); for (int i = 0 ; i < count; i++) { Method method = methodList[i]; SEL selector = method_getName(method);//方法入口 const char *sel_name = sel_getName(selector); NSLog(@"方法名 %s", sel_name); } free(methodList);
三、使用方向:归档、字典<---->模型、框架封装等
实现归档
#define WKCodingImplementing \ - (void)encodeWithCoder:(NSCoder *)aCoder \ { \ unsigned int ivarCount = 0; \ Ivar *ivarList = class_copyIvarList([self class], &ivarCount); \ for (int i = 0; i < ivarCount; i++) { \ Ivar ivar = ivarList[i]; \ const char *name = ivar_getName(ivar); \ const char *type = ivar_getTypeEncoding(ivar); \ NSLog(@"%s-----%s", name, type); \ NSString *key = [NSString stringWithUTF8String:name]; \ id value = [self valueForKey:key]; \ [aCoder encodeObject:value forKey:key]; \ } \ free(ivarList); \ } \ - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder \ { \ if (self = [super init]) { \ unsigned int ivarCount = 0; \ Ivar *ivarList = class_copyIvarList([self class], &ivarCount); \ for (int i = 0; i < ivarCount; i++) { \ Ivar ivar = ivarList[i]; \ const char *name = ivar_getName(ivar); \ NSString *key = [NSString stringWithUTF8String:name]; \ NSLog(@"%@ %@", key, value); \ id value = [aDecoder decodeObjectForKey:key]; \ [self setValue:value forKey:key]; \ } \ } \ return self; \ }