知识总结Objective-C Runtime 运行时(1)
来源:互联网 发布:数码兽传说 网络侦探pc 编辑:程序博客网 时间:2024/06/07 02:41
c语言不是动态语言,函数的调用在编译时候已经确定,编译完成后按照顺序执行即可。OC作为动态语言主要是因为Runtime库的支持,由于Runtime库的作用使得c语言具有了动态语言的特性,runtime保持在程序运行时创建,修改类,对象和方法,OC的函数调用通过runtime进行消息的转发。
Object-C类
typedef struct objc_class *Class;struct objc_class { Class _Nonnull isa OBJC_ISA_AVAILABILITY;#if !__OBJC2__ Class _Nullable super_class OBJC2_UNAVAILABLE;//父类 const char * _Nonnull name OBJC2_UNAVAILABLE;//类名 long version OBJC2_UNAVAILABLE;//类的版本信息 long info OBJC2_UNAVAILABLE;//类信息运行时的使用的标识位 long instance_size OBJC2_UNAVAILABLE;//实例变量大小 struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;//成员变量列表 struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;//方法列表 struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;//方法缓存 struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;//协议列表#endif} OBJC2_UNAVAILABLE;
下面定义两个类,并以此举例说明runtime
@interface Father : NSObject@property (nonatomic, strong) NSString *property_1_s;@property (nonatomic, weak) NSArray *property_2_w;@property (nonatomic, unsafe_unretained) id property_3_un;@property (nonatomic, weak) id property_4_w;@property (nonatomic, strong) id property_5_s;@property (nonatomic, strong) id property_6_s;@property (nonatomic, unsafe_unretained) id property_7_un;@property (nonatomic, strong) id property_8_s;@property (nonatomic, strong) id property_9_s;@property (nonatomic, weak) id property_10_w;@property (nonatomic, weak) id property_11_w;@property (nonatomic, strong) id property_12_s;@property (nonatomic, weak) id property_13_s;@end@interface Son : Father@endFather *father = [[Father alloc] init];Son *son = [[Son alloc]init];
(1)isa:指向metaClass(元类),元类顾名思义也是一个类,存储对象的类方法。
NSLog(@"This object is %p.", son);Class currentClass = [son class]; for (int i = 1; i < 5; i++) { NSLog(@"Following the isa pointer %d times gives %p", i, currentClass); currentClass = object_getClass(currentClass); } NSLog(@"NSObject's class is %p", [NSObject class]); NSLog(@"NSObject's meta class is %p", object_getClass([NSObject class]));
可以看出对象son的地址开辟在堆中,其类地址为0x109e80568,其isa指针指向的meta-class地址为0x109e80540,meta-class所属类的地址为0x10ae38e58,通过打印NSObject的地址可以看出meta-class继承了NSObject。
(2)super_class 指向父类,如果该类是最顶层根类如NSObject则其super_class为NULL。
(3)name 类名Father, Son
(4)version 该字段提供类的版本信息,可以识别出不同定义版本中的实例变量布局的改变
(5)instance_size 实例变量大小
NSInteger instance_size = class_getInstanceSize([father class]);NSLog(@"instance_size = %d",instance_size);
father含有13个属性都是指针类型和1个isa指针,一共112字节。
(6)ivars 它指向objc_ivar_list结构体,objc_ivar_list其实就是一个链表,存储多个objc_ivar,而objc_ivar结构体存储类的单个成员变量信息。
struct objc_ivar_list { int ivar_count OBJC2_UNAVAILABLE;#ifdef __LP64__ int space OBJC2_UNAVAILABLE;#endif /* variable length structure */ struct objc_ivar ivar_list[1] OBJC2_UNAVAILABLE;}
unsigned int outCount =0;Ivar*ivars =class_copyIvarList(father.class, &outCount); for(unsigned int i =0; i < outCount; ++i) { Ivar ivar = ivars[i]; const char*ivarName =ivar_getName(ivar); const char*ivarEncoder =ivar_getTypeEncoding(ivar); NSLog(@"Ivar name:%s Ivar TypeEncoder:%s",ivarName,ivarEncoder); } free(ivars);
(7)methodLists表示方法列表,它指向objc_method_list结构体的二级指针,可以动态修改*methodLists的值来添加成员方法,也是category的实现原理。
struct objc_method_list { struct objc_method_list * _Nullable obsolete OBJC2_UNAVAILABLE; int method_count OBJC2_UNAVAILABLE;#ifdef __LP64__ int space OBJC2_UNAVAILABLE;#endif /* variable length structure */ struct objc_method method_list[1] OBJC2_UNAVAILABLE;}
objc_method_list也是一个链表,存储多个objc_method,而objc_method结构体存储类的某个方法的信息。
typedef struct objc_method *Method; struct objc_method { SEL method_name OBJC2_UNAVAILABLE; char *method_types OBJC2_UNAVAILABLE; IMP method_imp OBJC2_UNAVAILABLE; }
Method是一个指向objc_method结构体指针,它存储了方法名(method_name)、方法类型(method_types)和方法实现(method_imp)等信息。而method_imp的数据类型是IMP,它是一个函数指针
(8)cache用于缓存最近使用的方法。一个对象接收到一个消息时,对象会根据isa指针去查找能够响应这个消息的对象。每次调用过一个方法后,这个方法就会被缓存到cache列表中,下次调用的时候runtime就会优先去cache中查找,如果cache没有,才去methodLists中查找方法。这样,对于那些经常用到的方法的调用,但提高了调用的效率。objc_cache结构体的指针,其定义如下:
struct objc_cache { unsigned int mask /* total = mask + 1 */ OBJC2_UNAVAILABLE; unsigned int occupied OBJC2_UNAVAILABLE; Method _Nullable buckets[1] OBJC2_UNAVAILABLE;};
(9)protocols类遵循的协议,协议列表objc_protocol_list定义如下:
typedef struct objc_object Protocol;//isa指针struct objc_protocol_list { struct objc_protocol_list * _Nullable next; long count; __unsafe_unretained Protocol * _Nullable list[1];};
- 知识总结Objective-C Runtime 运行时(1)
- Objective C运行时(runtime)要点总结
- Objective C运行时(runtime)技术总结
- Objective C运行时(runtime)技术总结,好强大的runtime
- Objective C运行时(runtime)技术总结,好强大的runtime
- Objective C运行时(runtime)技术总结,好强大的runtime
- Objective C运行时(runtime)技术总结,好强大的runtime
- Objective-C Runtime 运行时(2)
- Objective-C Runtime 运行时(3)
- Objective-C Runtime 运行时(4)
- Objective-C Runtime 运行时
- Objective-C Runtime 运行时
- Objective-C Runtime 运行时
- Objective C运行时(runtime)技术的几个要点总结
- Objective C运行时(runtime)技术的几个要点总结
- Objective C运行时(runtime)技术的几个要点总结
- Objective C运行时(runtime)技术的几个要点总结
- Objective C运行时(runtime)技术的几个要点总结
- 【web】javascript基础巩固——引用类型(二)
- jQ 数据在后台输出拼成完成的记录表,弹出事件没有效果
- TIME_LOG_START &&TIME_LOG_END
- kettle使用笔记(一)
- QuickSort
- 知识总结Objective-C Runtime 运行时(1)
- 软件调试笔记67
- Java面向对象知识点20个
- 总线错误和段错误
- C#游戏开发基础01
- 词向量模型扩展
- Visual Studio 2013下调试dll的问题
- streamsets安装部署
- 基于SpringBoot Shiro CAS单点登录实现