iOS Runtime原理
runtime的原理
ios的sdk中 usr/include/objc文件夹下面有这样几个文件
都是和运行时相关的头文件,其中主要使用的函数定义在message.h和runtime.h这两个文件中。 在message.h中主要包含了一些向对象发送消息的函数,这是OC对象方法调用的底层实现。
使用时,需要导入文件,导入如:
#import <objc/message.h>
#import <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.代表OC声明的属性
typedef struct objc_property *objc_property_t;
// Class代表一个类,它在objc.h中这样定义的 typedef struct objc_class *Class;
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
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;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
这些类型的定义,对一个类进行了完全的分解,将类定义或者对象的每一个部分都抽象为一个类型type,对操作一个类属性和方法非常方便。OBJC2_UNAVAILABLE标记的属性是Ojective-C 2.0不支持的,但实际上可以用响应的函数获取这些属性,例如:如果想要获取Class的name属性,可以按如下方法获取:
Class classPerson = Person.class;
// printf("%s\n", classPerson->name); //用这种方法已经不能获取name了 因为OBJC2_UNAVAILABLE
const char *cname = class_getName(classPerson);
printf("%s", cname); // 输出:Person
函数的定义
对对象进行操作的方法一般以object_开头
对类进行操作的方法一般以class_开头
对类或对象的方法进行操作的方法一般以method_开头
对成员变量进行操作的方法一般以ivar_开头
对属性进行操作的方法一般以property_开头开头
对协议进行操作的方法一般以protocol_开头
根据以上的函数的前缀 可以大致了解到层级关系。
对于以objc_开头的方法,则是runtime最终的管家,可以获取内存中类的加载信息,类的列表,关联对象和关联属性等操作。
例如:使用runtime对当前的应用中加载的类进行打印
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
unsigned int count = 0;
Class *classes = objc_copyClassList(&count);
for (int i = 0; i < count; i++) {
const char *cname = class_getName(classes[i]);
printf("%s\n", cname);
}
}
网友评论