RunTime机制详解(一)
来源:互联网 发布:购买域名怎么使用 编辑:程序博客网 时间:2024/06/05 20:14
了解RunTime机制能都让我们在对OC底层实现的认识有一个质的飞越,RunTime的功能十分强大。
一、利用RunTime机制来获取所有的属性
#pragma mark --- 获取所有属性/* 一、objc_property_t:声明属性的类型,是一个指向objc_property结构体的指针,只能获取所有的属性,并不能获取成员变量 typedef struct objc_property *objc_porperty_t; 二、操作函数 class_copyPropertyList 获取所有属性(并不会获取无@property声明的成员变量) property_getName 获取属性名 property_copyAttributeList 获取所有属性特性 property_getAttributes 获取属性特性描述字符串 (返回的是objc_property_attribute_t结构体列表,objc_property_attribute_t结构体包含name和value,常用属性如下: 属性类型 name值:T value:变化 编码类型 name值:C(copy) &(strong) W(weak) 空(assign)等 value:无 非/原子性 name值:空(atomic) N(nonatomic) value:无 变量名称 name值:V value:变化 ) */二、利用RunTime机制来获取成员变量。
#pragma mark --- 获取成员变量(成员变量)/* 一、 Ivar:实例变量类型,是一个指向objc_ivar结构体的指针,可以获取成员变量(包括私有成员变量)、属性 typedef struct objc_ivar *Ivar; 二、 操作函数 class_copyIvarList 获取所有成员变量 ivar_getName 获取成员变量名 ivar_getTypeEncoding 获取成员变量类型编码 class_getInstanceVarialbe 获取指定名称的成员变量 object_getIvar 获取某个对象成员变量的值 object_setIvar 设置某个对象成员变量的值 */+ (void)runtime_Ivars{ unsigned int outCount = 0; Ivar * ivars = class_copyIvarList([Property_Model class], &outCount); for (unsigned int i = 0; i < outCount; i ++) { Ivar ivar = ivars[i]; const char * name = ivar_getName(ivar); const char * type = ivar_getTypeEncoding(ivar); NSLog(@"类型为%s的%s",type,name); } free(ivars);}三、利用RunTime机制来获取私有变量
#pragma mark --- 访问私有变量+ (void)runtime_private_Property{ /** 我们知道,OC中没有真正意义上的私有变量和方法,要让成员变量私有,要放在m文件中声明,不对外暴露。如果我们知道这个成员变量的名称,可以通过runtime获取成员变量,再通过getIvar来获取它的值 */ Ivar ivar = class_getInstanceVariable([Property_Model class], "str_private"); Property_Model * model = [[Property_Model alloc] init]; [model modelPlay]; NSLog(@"%@",object_getIvar(model, ivar)); }
四、利用RunTime机制来快速实现归档解档
-(id)initWithCoder:(NSCoder *)aDecoder{ if (self = [super init]) { unsigned int outCount; Ivar * ivars = class_copyIvarList([self class], &outCount); for (int i = 0; i < outCount; i ++) { Ivar ivar = ivars[i]; NSString * key = [NSString stringWithUTF8String:ivar_getName(ivar)]; [self setValue:[aDecoder decodeObjectForKey:key] forKey:key]; } } return self;}-(void)encodeWithCoder:(NSCoder *)aCoder{ unsigned int outCount; Ivar * ivars = class_copyIvarList([self class], &outCount); for (int i = 0; i < outCount; i ++) { Ivar ivar = ivars[i]; NSString * key = [NSString stringWithUTF8String:ivar_getName(ivar)]; [aCoder encodeObject:[self valueForKey:key] forKey:key]; }}
五、字典转模型的内部实现
我们都知道字典转模型的方法,但并不明白其中真正的方法实现,我们要的是知其然也要知其所以然。
-(instancetype)initWithDict:(NSDictionary *)dic{ if (self = [self init]) { NSMutableArray * keys = [NSMutableArray array]; NSMutableArray * attributes = [NSMutableArray array]; unsigned int outCount; objc_property_t * properties = class_copyPropertyList([self class], &outCount); for (int i = 0 ; i < outCount; i ++) { objc_property_t property = properties[i]; //通过property_getName函数获得属性的名字 NSString * propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding]; [keys addObject:propertyName]; //通过property_getAttributes函数可以获得属性的名字和@encode编码 NSString * propertyAttribute = [NSString stringWithCString:property_getAttributes(property) encoding:NSUTF8StringEncoding]; [attributes addObject:propertyAttribute]; } free(properties);//立即释放properties指向的内存 for (NSString * key in keys) { if ([dic valueForKey:key] == nil) continue; [self setValue:[dic objectForKey:key] forKey:key]; } } return self;}
代码传送门:https://github.com/fuzongjian/RuntimeStudy.git
0 0
- RunTime机制详解(一)
- RunTime机制详解(二)
- iOS RunTime 机制浅析(一)
- oc 的 runtime机制(一)
- Android runtime机制(一)init进程
- iOS runTime 机制详解
- RunTime机制详解(三)
- RunTime机制详解(四)
- RunTime机制详解(五)
- runTime详解一
- Runtime详解一
- Objective-C Runtime机制详解
- runtime浅谈(一)动态运行时和消息机制
- runtime的那点事儿(一)消息机制
- Runtime的那点事儿(一)消息机制
- runtime机制(1)
- Runtime(消息机制)
- Runtime那点事(消息机制一)
- IOS开发之----资源汇总
- 图像大小转换-转载
- 数据库优化的思路
- arcgis一直处于初始化状态的原因
- android_自定义对象如何装入bundle
- RunTime机制详解(一)
- 设计模式之外观模式(Facade)
- 将整数A转换为B
- 侧滑菜单之 DrawerLayout
- 斜率优化dp简讲 && HDU 3507 Print Article
- <Python><Ubuntu>安装geopandas
- Hbase启动报错Region server exiting
- 如何在Ubuntu 16.04中创建GIF动图
- 木材加工