Objective-C是C语言的扩展,让C具备了面向对象的能力,而且它是一门动态语言。这都要归功于runtime。或者可以说,Objective-C = C + Runtime;
Runtime的开源是热更的产生基础条件,然而苹果因为“安全因素”又禁止了热更,JSPatch目前正在努力解决安全问题,从脚本内容RSA加密,到搜索敏感私有接口调用。理论上来讲,ios应用可以完全依托于JSPatch做开发,就避免了发版和升级的烦恼。
内存模型:
Class:
typedef struct objc_class *Class;
struct objc_class {
Class isa; //指向meta_class
Class super_class; //指向父类
const char* name;
long version;
long info;
long instance_size;
struct objc_ivar_list *ivars; //类的成员变量,使用数组存储,使用中基本不变化(只有动态生成的类才能添加成员变量Ivar),存取效率高。
struct objc_method_list **methodLists; //类的成员方法,使用链表存储。使用中可能会增加方法,使用链表存储。
struct objc_cache *cache; //类的方法缓存。
struct objc_protocol_list *protocols; //类遵守的协议。
};
需要区分的是,Class和meta-Class的cache内容不同,Class的cache里面都是实例方法,meta-Class的cache里面都是类方法。
Meta-Class
获取meta-class的方法。
objc_getClass((__bridge void*)[NSObject class])
Class objc_getMetaClass(const char* name) //name: The name of the class to look up
对象
struct objc_object {
Class isa; //指向对象所属的类。
};
typedef struct objc_object *id;
当创建一个特定类的实例对象时,分配的内存包含一个objc_object数据结构,然后是类的实例变量的数据。
NSObject类的alloc和allocWithZone:方法使用函数class_createInstance来创建objc_object数据结构。
我们常见的id,它是一个objc_object结构类型的指针。它的存在可以让我们实现类似于C++中泛型的一些操作。该类型的对象可以转换为任何一种对象,有点类似于C语言中void *指针类型的作用。C语言中void * 为 “不确定类型指针”,void *可以用来声明指针。如:void * a;
Method
structobjc_method {
SEL method_name; //选择器
char* method_types;//参数types是一个描述传递给方法的参数类型的字符数组,这涉及到类型编码。
IMP method_imp; //函数指针。
}
SEL
typedef struct objc_selector *SEL
选择器,用于定位一个方法,可以理解为一个字符串。
runtime.h并没有提供SEL结构体的具体实现。而只是定义了SEL,typedef struct objc_selector *SEL; 可以这样理解,方法名和SEL之间存在一种映射关系,理论上SEL是对方法名做一个hash处理。只是猜测。无论方法名与SEL之间的映射是怎样的,它们两个都是用来区分一个方法。但是需要注意,runtime官方用来标识一个Method的是Method的SEL,而不是方法名。
IMP
typedef id (*IMP) (id,SEL, ...);
可以看出IMP就是一个函数指针,它的前两个参数id代表消息接受者self,SEL代表方法选择器cmd。
成员变量
typedef struct objc_ivar * Ivar;
struct objc_ivar {
char* ivar_name;
char* ivar_type;
int ivar_offset;
int space;
}
Property
typedef struct objc_property *objc_property_t;
Category
typedef struct objc_category *Category;
structobjc_category {
char* category_name;
char* class_name;
struct objc_method_list *instance_methods ;
struct objc_method_list *class_methods;
struct objc_protocol_list *protocols;
}
Protocol
typedef struct objc_object Protocol;
一个经典的指向图
注意两个特殊连线:
1,所有元类的isa指针指向的是根类的元类。
2,根类的元类的父类指向的是根类本身。