码迷,mamicode.com
首页 > 移动开发 > 详细

iOS运行时 runtime

时间:2015-05-31 12:32:34      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:runtime

1、运行时介绍

1. 什么是运行时

运行时机制是用 C++开发的,是一套苹果开源的框架

OC 是基于运行时开发的语言,在OC所有的类都是运行的时候才加载。

2. OC语言

OC 是一个全动态语言,OC的一切都是基于 Runtime实现的

只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法


3. 使用场景

1. 运行时动态获取类的属性

//主要应用:字典转模型框架 MJExtensionJSONModel

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;
}

实例源码 点击打开链接












iOS运行时 runtime

标签:runtime

原文地址:http://blog.csdn.net/wangxiaoit/article/details/46284963

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!