第一次看到runtime時,以爲過高大上,動態獲取方法、屬性等簡直厲害的不要不要的。在通過查找資料+實踐後,發現runtime並無想象中那麼複雜,接下來對runtime進行基本的介紹。數組
要使用運行時方法須要引入runtime.h文件框架
1、基礎知識 spa
Method :成員方法code
Ivar : 成員變量blog
2、經常使用方法get
class_copyPropertyList : 獲取屬性列表string
class_copyMethodList : 獲取成員方法列表it
class_copyIvarList:獲取成員變量列表class
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);
3、使用方向:歸檔、字典<---->模型、框架封裝等
實現歸檔
#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; \ }