对象和类
简单概括,理解‘一个模子刻出来的’这句话就基本理解了类和对象的关系。
如上图:
对象-->类对象-->元类对象,本文暂不讨论元类,可以看到 对象的isa指向类对象。
typedef struct objc_class *Class;
typedef struct objc_object *id;
类对象本质上是一个objc_class的结构体,对象是一个objc_object的结构体,objc_object第一个成员就是isa。
isa是个什么鬼
isa是个isa_t的联合体,其定义经过删减拼凑大概如下(from objc-818):
union isa_t {
uintptr_t bits;
Class cls;
struct {
#if arm64e
uintptr_t nonpointer : 1; \
uintptr_t has_assoc : 1; \
uintptr_t weakly_referenced : 1; \
uintptr_t shiftcls_and_sig : 52; \
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 8;
#elif arm64
uintptr_t nonpointer : 1; \
uintptr_t has_assoc : 1; \
uintptr_t has_cxx_dtor : 1; \
uintptr_t shiftcls : 33; /*MACH_VM_MAX_ADDRESS 0x1000000000*/ \
uintptr_t magic : 6; \
uintptr_t weakly_referenced : 1; \
uintptr_t unused : 1; \
uintptr_t has_sidetable_rc : 1; \
uintptr_t extra_rc : 19;
#else
...
#endif
};
};
-nonpointer
:标识isa是不是个指针,值为1时非指针,也就是isa这时候对应isa_t中的结构体;值为0时,表示是个指针,对应Class,也就是指向objc_class类型的结构体。
下面分析下普通arm64下的
-has_assoc
:标识位,具体用途暂时没看
-has_cxx_dtor
:有无c++析构函数
-shiftcls
:经处理后类对象的地址(处理回来能找到类对象)
-magic
:具体用途暂时没看
-weakly_referenced
:对象有没有被弱引用
-unused
:没用不用管
-extra_rc
:引用计数值
-has_sidetable_rc
:当extra_rc溢出不够用了,需要采用sidetable时为true
对象的实例化流程
1.+ alloc
底层实现大概可总结为三步:
- 计算需要的size
- calloc开辟空间
- 接下来initisa,将开辟的空间与类对象关联
2.- init
其实init方法啥也没干,比如initWithXXX等,一个作用可能就是给这种支撑吧
id
_objc_rootInit(id obj)
{
// In practice, it will be hard to rely on this function.
// Many classes do not properly chain -init calls.
return obj;
}