iOS开发-------初探运行时runtime
来源:互联网 发布:vr用什么软件 编辑:程序博客网 时间:2024/06/05 19:35
对于iOS的开发者,相信Objc的runtime机制肯定都听说过,了解runtime的机制,对自己的提高不言而喻,最近在一直学习runtime机制,对此写下点学习过程的收获,以便以后查阅,也方便理解,本人研究runtime时间不长,如果有理解不对的地方也请告知,共同进步。
什么叫runtime呢,大家也都知道Objc的底层是C语言完成的,在运行的时候,会将Objc的代码转换成C语言的代码,这段过程就是所说的运行时runtime。比如执行一个方法的执行: [target action];这段代码会在runtime的时候转换为objc_msgSend(target,@selector(action));
要想了解RunTime,首先了解的必然是类的结构,在Objc中所有的东西都可以看做是一个对象,实例对象是一个对象,类也是一个对象,打开objc/runtime.h,研究一下他的结构:
/// An opaque type that represents a method in a class definition.typedef struct objc_method *Method;//描述类的一个方法/// An opaque type that represents an instance variable.typedef struct objc_ivar *Ivar;//实例变量/// An opaque type that represents a category.typedef struct objc_category *Category;//类目/// An opaque type that represents an Objective-C declared property.typedef struct objc_property *objc_property_t;//类中声明的属性
struct objc_class { Class isa OBJC_ISA_AVAILABILITY;//指向类结构的指针#if !__OBJC2__ Class super_class OBJC2_UNAVAILABLE;//父类,如果此类是根类,则为NULL const char *name OBJC2_UNAVAILABLE;//类名 long version OBJC2_UNAVAILABLE;//版本号 long info OBJC2_UNAVAILABLE;//标志位 long instance_size OBJC2_UNAVAILABLE;//实例对象的大小 struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;//实例变量的列表,没有则为NULL struct objc_method_list **methodLists OBJC2_UNAVAILABLE;//存储对象方法列表,没有则为NULL struct objc_cache *cache OBJC2_UNAVAILABLE;//缓存最近使用过的方法,提高运行效率 struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;//存储遵守正式协议的列表,没有则为NULL#endif} OBJC2_UNAVAILABLE;
看到这段代码,想起之前看到过罗朝辉出过的一本书,上面在这里面讲的一句话是"内存布局以一个objc_class指针为开始的所有东东都可以当做一个object来对待"。
isa指针是个什么东东呢,它是一个Class类型的指针,如果这个类是一个实例对象(instance object),那么它的isa指针就指向它所属于的类对象的类(class 实例对象的isa指针指向的类对象为class,class中存储着普通成员变量以及普通的方法,即-方法),如果这个类是一个类对象(class object),那么它的isa指针就指向了metaClass(类对象isa指向的类结构为metaclass,metaclass中存储着类的Static类成员变量以及Static方法,即+方法)
如果有点乱的话,官方有一张图很清晰的描述了他们之间的关系,如下
只说无代码是枯燥的,为了测试一下简单的RunTime机制,创建一个RunTimeTextClass类
//// RunTimeTextClass.h// RunTime//// Created by YueWen on 16/2/21.// Copyright © 2016年 YueWen. All rights reserved.//#import <Foundation/Foundation.h>@protocol Protocol1;@protocol Protocol2;@interface RunTimeTextClass : NSObject<Protocol1>{ NSString * ival1; NSString * ival2;}@property (copy, nonatomic)NSString * title;@property (assign, nonatomic)NSInteger index;- (void)objctFunction;+ (void)classFunction;@end@protocol Protocol1 <NSObject>@optional- (void)text1;@end@protocol Protocol2 <NSObject>@optional- (void)text2;@end
//// RunTimeTextClass.m// RunTime//// Created by YueWen on 16/2/21.// Copyright © 2016年 YueWen. All rights reserved.//#import "RunTimeTextClass.h"@interface RunTimeTextClass()<Protocol2>{ NSString * ival1M;}@property (nonatomic, copy)NSString * titleM;//.m中的属性@end@implementation RunTimeTextClass-(void)objctFunction{ }@end
获取类的属性列表
//获取类的属性列表unsigned int propertyCount;objc_property_t * propertyList = class_copyPropertyList([RunTimeTextClass class], &propertyCount);//获取属性的数组列表for (int i = 0; i < propertyCount; i ++)//开始遍历{ //获取属性名字 const char * name = property_getName(propertyList[i]); NSLog(@"property = %@",[NSString stringWithUTF8String:name]);}
打印结果如下:
获取类的实例变量列表
//获取类的实例变量列表unsigned int ivarCount;Ivar * ivars = class_copyIvarList([RunTimeTextClass class], &ivarCount);//获取实例变量的列表for (int i = 0; i < ivarCount; i++)//开始遍历{ //获取实例变量的名字 const char * name = ivar_getName(ivars[i]); NSLog(@"ivar = %@",[NSString stringWithUTF8String:name]);}
打印结果如下: 从结果来看,每创建一个属性,运行时会响应的创建一个_(propertyName)的实例变量
获取类中已经实现的方法列表
//获取已经实现的方法列表 unsigned int methodCount; Method * methods = class_copyMethodList([RunTimeTextClass class], &methodCount); for (int i = 0; i < methodCount; i++) { //获取方法名字 Method method = methods[i]; NSLog(@"method = %@",NSStringFromSelector(method_getName(method))); }
运行结果如下:看出没有实现的方法并没有进行打印,并且用@property声明的变量在RunTime会自行的创建它的Get和Set方法
获取遵守的协议列表
//获取协议的列表 unsigned int protocolCount; __unsafe_unretained Protocol ** protocols = class_copyProtocolList([RunTimeTextClass class], &protocolCount); for (int i = 0; i < protocolCount; i++) { //获取协议 Protocol * protocol = protocols[i]; //获得协议名称 const char * name = protocol_getName(protocol); NSLog(@"Protocol = %@",[NSString stringWithUTF8String:name]); }
运行结果如下:(Protocol2是在延展中遵守,Protocol1是在声明文件中遵守)
RunTime到底有什么用呢,比如字典转模型的时候,我想属性的名字和字典的索引名字相同,但是实际上属性的名称与字典的key值并不匹配,那么就可以在RunTime中对类进行添加属性。RunTime研究起来很有意思,想以后会陆续的写一些关于RunTime的东西。
- iOS开发-------初探运行时runtime
- iOS开发之Runtime初探
- IOS开发——Runtime运行时
- iOS开发之运行时Runtime
- iOS运行时 runtime
- iOS runtime 运行时
- IOS runtime运行时
- iOS--RunTime运行时
- iOS runtime运行时
- iOS开发——RunTime(运行时)
- iOS 开发之 runtime运行时模拟成员变量
- iOS开发之运行时编程(Runtime Programming)浅读
- iOS开发之关于Runtime运行时:类与对象
- iOS runtime 初探
- iOS运行时(Runtime)总结
- iOS RunTime 运行时 介绍
- iOS runtime运行时详解
- iOS运行时Runtime浅析
- 警惕提供收费服务的小公司之Shadowsocks.com
- C#基础之数据类型Int64
- Android Studio各个版本的区别
- BestCoder Round #73(div.2)
- 谈谈 Hash Table
- iOS开发-------初探运行时runtime
- Android:SQLite数据绑定ListView
- win10 UWP 单元测试
- 如何使用TestFlight进行Beta测试
- 算法竞赛入门经典(第二版)-刘汝佳-第五章 C++与STL 习题(13/16)
- ubuntu下latex安装(含中文环境)
- MongoDb的基本使用以和关系性数据库的基本差异
- 51单片机系列知识2--存储器(1)
- hrbust 哈理工oj 1352 中间的球【floyd递推关系过】