问题:
- 对象的isa指针指向哪里
- 实例对象的isa指向类对象
- 类对象的isa指向元类对象
- 元类对象的isa指向基类的元类对象
- oc对象的信息存储在哪里?
- 对象方法、属性、成员变量、协议存储在class对象中
- 类方法存储在元类对象中
- 成员变量的值存储在实例对象中
object-c中的对象主要分为3种:
- instance对象(实例对象)
- class对象(类对象)
- meta-class对象(元类对象)
instance对象
- instance对象就是通过类alloc出来的对象,每次调用alloc都会产生新的instance对象
- 内存中存储着:
- isa指针
- 其他成员变量
class对象
- 每个类对象在内存中有且只有一个class对象
- 内存中存储着:
- isa指针
- superclass指针
- 类的属性信息(@property)、类的对象方法信息(instance > * method)
- 类的协议信息(protocol)、类的成员变量信息(ivar)
- 其他成员变量
meta-class对象
- 即类对象的isa所指向的对象,每个类在内存中有且只有一个meta-class对象
- meta-class对象和class对象的内存结构是一样的,但是用途不一样
- 通过
object_getclass
可获取到元类对象 - 内存中存储着:
- isa指针
- superclass指针
- 类的属性信息(@property)、类的对象方法信息(instance > * method)
- 类的协议信息(protocol)、类的成员变量信息(ivar)
- 其他成员变量
三种对象的isa和superclass指针之间的关系
-
isa指针
-
class对象的superclass指针
-
meta-class对象的superclass指针
-
总结
class结构
从底层来看,class和meta-class都是objc_class结构
struct objc_class {
Class ISA;
Class superclass;
cache_t cache; // 方法缓存
class_data_bits_t bits; // 类的具体信息,想要&FAST_DATA_MASK才能获取到正确的地址
...
};
class_data_bits_t结构大体:
struct class_data_bits_t {
class_rw_t* data; //存储类的信息
...
}
class_rw_t大体结构:
struct class_rw_t {
uint32_t flags;
uint16_t witness;
explicit_atomic<uintptr_t> ro_or_rw_ext;
Class firstSubclass;
Class nextSiblingClass;
using ro_or_rw_ext_t = objc::PointerUnion<const class_ro_t *, class_rw_ext_t *>;
const ro_or_rw_ext_t get_ro_or_rwe();
const class_ro_t *ro();
const method_array_t methods(); //方法列表
const property_array_t properties(); //属性列表
const protocol_array_t protocols(); //协议列表
...
};
其中ro结构体为:
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize; //实例创建出来的占用的空间大小
#ifdef __LP64__
uint32_t reserved;
#endif
const uint8_t * ivarLayout;
const char * name; //类名
method_list_t * baseMethodList;
protocol_list_t * baseProtocols;
const ivar_list_t * ivars;
const uint8_t * weakIvarLayout;
property_list_t *baseProperties;
...
};
小细节:define ISA_MASK 0x0000000ffffffff8ULL
可以发现isa指向的类或者元类对象的地址,最后三位都是0。