1、运行时介绍
1. 什么是运行时
运行时机制是用 C++开发的,是一套苹果开源的框架OC
是基于运行时开发的语言,在OC中所有的类都是运行的时候才加载。2. OC语言
OC 是一个全动态语言,OC的一切都是基于 Runtime实现的只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法
3. 使用场景
1. 运行时动态获取类的属性//主要应用:字典转模型框架 MJExtension,JSONModel
2.利用关联对象为分类添加属性
3.利用交换方法拦截系统或其他框架的方法
//误区:并不是使用的技术越底层,框架的效率就会越高
4. 头文件
#import <objc/runtime.h>
2、运行时应用
1. 运行时获取列的属性等相关信息
1. 获取类的属性列表
/** 如果要想动态的获取类的属性,需要使用到“运行时机制” class_copyIvarList 成员变量 class_copyPropertyList 属性 class_copyMethodList 方法 class_copyProtocolList 协议 */ /// 返回类的属性列表 + (NSArray *)propertyList { // 0. 判断是否存在关联对象, 如果存在, 直接返回 /** 参数 1> 关联到得对象 2> 关联的属性 key */ NSArray *plist = objc_getAssociatedObject(self, propertiesKey); if (plist) { return plist; } // 1. 获取 '类的属性' /** 1> 类 2> 属性的计数指针 */ unsigned int count = 0; // 返回值是所有属性的数组 obj_property_ objc_property_t *list = class_copyPropertyList([self class], &count); // 创建 存储属性数组 NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:count]; for (int i = 0; i < count; ++i) { // 获取属性 objc_property_t pty = list[i]; // 获取属性名 const char *cname = property_getName(pty); [arrayM addObject:[NSString stringWithUTF8String:cname]]; } // 释放属性数组 free(list); // 设置关联对象 /** 1> 关联的对象 2> 关联对象的 key 3> 属性数值 4> 属性的持有方式 reatin, copy, assign */ objc_setAssociatedObject(self, propertiesKey, arrayM, OBJC_ASSOCIATION_COPY_NONATOMIC); return arrayM.copy; }字典转模型方法
/// 字典转模型方法 + (instancetype)objectWithDict:(NSDictionary *)dict { id obj = [[self alloc] init]; // 获取属性列表 NSArray *properties = [self propertyList]; // 遍历属性数组 for (NSString *key in properties) { // 判断字典中是否包含这个key if (dict[key] != nil) { // 使用 KVC 设置属性值 [obj setValue:dict[key] forKeyPath:key]; } } return obj; }2. 返回类的方法列表
/// 返回类的方法列表 + (NSArray *)methodList { // 0. 判断是否存在依赖关系 NSArray *mlist = objc_getAssociatedObject(self, methodsKey); if (mlist) { return mlist; } unsigned int count = 0; // 1. 获取方法列表 Method *list = class_copyMethodList([self class], &count); // 存储方法数组 NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:count]; for (int i = 0; i < count; ++i) { // 获取方法 Method method = list[i]; // 获取方法名 SEL mname = method_getName(method); [arrayM addObject: NSStringFromSelector(mname)]; } // 释放数组 free(list); // 设置依赖关系 objc_setAssociatedObject(self, methodsKey, arrayM, OBJC_ASSOCIATION_COPY_NONATOMIC); return arrayM.copy; }3. 返回类的实现协议列表
/// 返回类的实现协议列表 + (NSArray *)protocolList { // 0. 判断是否存在依赖关系 NSArray *pList = objc_getAssociatedObject(self, protocolKey); if (pList) { return pList; } unsigned int count = 0; // 2. 获取协议列表 Protocol * __unsafe_unretained *list = class_copyProtocolList([self class], &count); // 创建协议数组 NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:count]; for (int i = 0; i < count; ++i) { // 获取协议 Protocol * __unsafe_unretained prot = list[i]; const char *pname = protocol_getName(prot); [arrayM addObject:[NSString stringWithUTF8String:pname]]; } return arrayM; }实例源码 点击打开链接
时间: 2024-10-11 17:18:22