Runtime初学习
什么是runtime?
runtime是一套纯c的API.平时用oc写的代码在运行时都会先转成runtime代码,然后在执行。
runtime可以干什么?
1.交换方法。(method_exchangeImplementations)
首先创建一个People类,有俩个类方法,+(void)run{NSLog@"跑"}和+(void)sing{NSLog@"唱歌"}.
依次调用这两个方法,控制台会依次输出 跑 和 唱歌 。
用runtime获取到People类的run方法。
Method m1=class_getClassMethod([People class], @selector(run)) ;
同理获取sing方法。
Method m2=class_getClassMethod([People class], @selector(sing)) ;
交换两个方法。
method_exchangeImplementations(m1, m2) ;
在依次调用这个两个方法,控制台会输出 唱歌 和 跑。
实例方法用 class_getInstanceMethod 来获取。
2.在分类中设置属性。
众所周知,在分类中是无法添加实例变量的。就算在分类中声明了一个属性,也只是生成了这个属性的set方法和get方法,并不会生成这个属性。并且,虽然打点调用会有
提示,但是一旦运行程序就会崩溃。所以要想在分类中添加实例变量还得使用runtime来操作。
使用到的是
void objc_setAssociatedObject(id object , const void *key ,id value ,objc_AssociationPolicy policy) 这个方法。
其中:
object就是你想要添加属性的对象。
key则是你想保存的属性的键。
value则是你想保存的属性的值。
policy则是你想保存的属性的属性(assign,copy之类的)。
比如在一个分类中声明了一个属性。
@property(nonatomic,copy)NSString* name
在其set方法中这么调用:
char nameKey ;//声明属性的键。
-(void)setName:(NSString *)name
{
objc_setAssociatedObject(self, &nameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC) ;//关联 键和值
}
在其get方法中这么调用来获取这个属性:
-(NSString* )name
{
return objc_getAssociatedObject(self, &nameKey) ;
}
这样就在分类中添加了一个属性。
3.获取一个类的所有属性。
-(void)getPropertyFromPeople
{
unsigned int outcount ;
Ivar* ivars=class_copyIvarList([People class],&outcount) ;//会返回属性的个数,outcount即为总个数
for(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",name,type) ;
}
free(ivars) ;//注意释放内存
}
4.将dict转换成model类。
将方法写在NSObject的分类中,然后model类继承于NSObject,在导入分类的头文件。
-(instancetype)modelWithDictionary:(NSDictionary* )dict
{
Class modelClass=self.class ;
while (modelClass&&modelClass!=[NSObject class]) {
unsigned int count=0 ;
Ivar* ivars=class_copyIvarList(modelClass, &count) ;
for (int i=0; i<count; i++) {
Ivar ivar=ivars[i] ;
NSString* key=[NSString stringWithUTF8String:ivar_getName(ivar)] ;
key=[key substringFromIndex:1] ;
id value=dict[key] ;
if (value==nil) {
continue ;
}
NSString* type=[NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)] ;
//type的格式为@“@\“NSString\””
NSRange range=[type rangeOfString:@"@"] ;
if (range.location!=NSNotFound) {
if (![type containsString:@"NS"]) {
//是自定义的类型
Class another=NSClassFromString([type substringWithRange:NSMakeRange(2, type.length-3)]) ;
value=[another secondModelWithDictionary:value] ;
}else if([[type substringWithRange:NSMakeRange(2, type.length-3)] isEqualToString:@"NSArray"])
{
//包含数组
//包含model数据的数组
NSArray* array=(NSArray* )value ;
NSMutableArray* modelArr=[NSMutableArray array] ;
//用于接收数组中model的类型
id class ;
if ([self respondsToSelector:@selector(classStringByArray)]) {
class=[self classStringByArray] ;
for (int i=0; i<array.count; i++) {
//将数组的数据转换成model添加到临时数组中
[modelArr addObject:[class secondModelWithDictionary:array[i]]] ;
}
value=modelArr ;
}
}
}
[self setValue:value forKey:key] ;
}
free(ivars) ;
modelClass=[modelClass superclass] ;
}
return self ;
}
+(instancetype)secondModelWithDictionary:(NSDictionary* )dict
{
NSObject* object=[[self alloc]init] ;
[object modelWithDictionary:dict] ;
return object ;
}
Runtime初学习的更多相关文章
- clisp, scheme 和 clojure 初学习
clisp, scheme和clojure 初学习 1 clojure "clojure绝对会成为你的编程工具箱里的终极武器" "其他语言可能只是工具,但 Clojure ...
- c# window服务-初学习
window服务-初学习 一.工具: VS2015+NET Framework4.5. 二.操作: 1.新建windows服务的项目: 2.修改windows服务相关内容: 3.预览windows服务 ...
- Python初学习:简单的练习题
Python初学习 一些见到那的练习题: 初级难度 设计一重量转换器,输入以g为单位的数字后,返回换算结果以Kg为单位的结果 中级难度 设计一个求直角三角形斜边长的函数,(以两个直角边为参数,求最长边 ...
- iOS runtime 初步学习
注: 在Xocde5之后, 使用运行时方法需要进行2步设置1. 在Build Setting中搜索'msg', 设置'Strict Checking' 为 NO2. 使用需要导入头文件 #import ...
- runtime 初入
一.runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 对于C语言,函数的调用在编译的时候会决定调用哪个函数. 对于OC的函数,属于 ...
- Swift初学习
距离swift发布10天了,也简单看了一下swift的语法,个人感觉相对于object-c很是简单明了.Swift的出现并不能说明iOS开发简单了很多,有可能会变得复杂,你需要学习两门编程语言,因为在 ...
- Jquery 插件初学习
参考文章:插件开发精品教程,让你的jQuery提升一个台阶 刚刚学了一下jquery的插件插件开发,写个demo记录.练习一下.毕竟,输出才是最好的学习. 这个也不过是最基础的一个插件写法,只是,自己 ...
- requests库写接口测试框架初学习
学习网址: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dscpm/ff75b907-415d-4220-89 ...
- 2018.2.21 Python 初学习
折腾了一天,一直在用CMD学习Python写Hello World.偶然间发现可以用Pycharm.也算是给后面想学习的人提个醒,方便省事许多. format()使用方法. age = 20name ...
随机推荐
- vue.js 1中父组件跳到子组件中并传参让子组件显示不同的内容
父组件中的点击跳转: <ul class="insurance-entry clearfloat"> <li v-link="{name:'produc ...
- 重构MVC多条件+分页解决方案
为支持MVC的验证,无刷新查询,EF,以及让代码可读性更强一点,所以就重构了下原来的解决方案. 这里就简单讲下使用方法吧: Model: 继承PagerBase: 1 public class Sea ...
- 跳过 centos部署 webpy的各种坑
用centos部署webpy发现的各种坑: 1.python 版本: 2.中文编码: 3.web模块路径: 在命令行里输入python,能import web,但是网站错误报告一直报告没有找到web模 ...
- iptables删除规则
查看nat规则: iptables -t nat -nL --line-number 添加规则是-A和-I,-A是添加到末尾,-I是添加到指定位置,默认添加到最前面.删除使用-D,也就是原来“ipta ...
- unity游戏在logcat中过滤一些不需要的Log
adb logcat | grep -v "UnityEngineDebug.cpp\|:\s*$" | grep Unity 意义: 1. grep -v "过滤条件1 ...
- X-Cart 学习笔记 完整目录
如果有需要,可以直接联系博主,讨论学习 一.了解X-CART. 3 二.PHP环境搭建... 3 三.安装配置X-CART. 4 1.下载X-Cart并配置域名,映射地址... 4 2.配置X-Car ...
- 转:C# 中 MSCHART 饼状图显示百分比
转自:http://blog.sina.com.cn/s/blog_51beaf0e0100yffo.html 1)显示百分比 Chart1.Series["Series1"].L ...
- 测不准的程序员(Heisenberg Developers)
摘译自http://mikehadlow.blogspot.co.uk/2014/06/heisenberg-developers.html ——“你无法在不改变他们状态的情况下观察一个开发者” ...
- .net工作准备系列--01前言
注:学习参考朱毅编著的进入IT名企必读200题. 内容重在自我学习与巩固. 前言: 章节划分 01应聘须知 02基础知识(重点) 03进阶知识 04重点应用(aspnet第一部分) 04重点应用(as ...
- 如何存session,取session
存session: Session["codes"] =要存的session字段 用哈希函数存多个: System.Collections.Hashtable hs = new S ...