在开始写这篇文章之前,我们首先应该弄明白一个问题。那就是isa到底是什么? 在官方的解释中是这样的
Every object is connected to the run-time system through itsisa instance variable, inherited from the NSObject class.isa identifies the object's class; it points to a structurethat's compiled from the class definition. Through isa, anobject can find whatever information it needs at run timesuch asits place in the inheritance hierarchy, the size and structure ofits instance variables, and the location of the methodimplementations it can perform in response to messages.
翻译过来的意思就是 每个对象都通过从NSObject类继承的isa实例变量来连接到运行时系统。 它指向从类定义编译的结构。 通过isa,对象可以找到运行时所需的任何信息,例如其在继承层次结构中的位置,其实例变量的大小和结构以及可以响应消息执行的方法实现的位置。
isa的结构
union isa_t {
isa_t() { }
isa_t(uintptr_t value) : bits(value) { }
Class cls;
uintptr_t bits;
#if defined(ISA_BITFIELD)
struct {
ISA_BITFIELD; // defined in isa.h
};
#endif
};
其中ISA_BITFIELD是一个宏定义,它定义的结构如下
#if SUPPORT_PACKED_ISA
// extra_rc must be the MSB-most field (so it matches carry/overflow flags)
// nonpointer must be the LSB (fixme or get rid of it)
// shiftcls must occupy the same bits that a real class pointer would
// bits + RC_ONE is equivalent to extra_rc + 1
// RC_HALF is the high bit of extra_rc (i.e. half of its range)
// future expansion:
// uintptr_t fast_rr : 1; // no r/r overrides
// uintptr_t lock : 2; // lock for atomic property, @synch
// uintptr_t extraBytes : 1; // allocated with extra bytes
# if __arm64__
# define ISA_MASK 0x0000000ffffffff8ULL
# define ISA_MAGIC_MASK 0x000003f000000001ULL
# define ISA_MAGIC_VALUE 0x000001a000000001ULL
# define ISA_BITFIELD \
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 deallocating : 1; \
uintptr_t has_sidetable_rc : 1; \
uintptr_t extra_rc : 19
# define RC_ONE (1ULL<<45)
# define RC_HALF (1ULL<<18)
# elif __x86_64__
# define ISA_MASK 0x00007ffffffffff8ULL
# define ISA_MAGIC_MASK 0x001f800000000001ULL
# define ISA_MAGIC_VALUE 0x001d800000000001ULL
# define ISA_BITFIELD \
uintptr_t nonpointer : 1; \
uintptr_t has_assoc : 1; \
uintptr_t has_cxx_dtor : 1; \
uintptr_t shiftcls : 44; /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ \
uintptr_t magic : 6; \
uintptr_t weakly_referenced : 1; \
uintptr_t deallocating : 1; \
uintptr_t has_sidetable_rc : 1; \
uintptr_t extra_rc : 8
# define RC_ONE (1ULL<<56)
# define RC_HALF (1ULL<<7)
# else
# error unknown architecture for packed isa
# endif
// SUPPORT_PACKED_ISA
#endif
#if SUPPORT_INDEXED_ISA
# if __ARM_ARCH_7K__ >= 2 || (__arm64__ && !__LP64__)
// armv7k or arm64_32
# define ISA_INDEX_IS_NPI_BIT 0
# define ISA_INDEX_IS_NPI_MASK 0x00000001
# define ISA_INDEX_MASK 0x0001FFFC
# define ISA_INDEX_SHIFT 2
# define ISA_INDEX_BITS 15
# define ISA_INDEX_COUNT (1 << ISA_INDEX_BITS)
# define ISA_INDEX_MAGIC_MASK 0x001E0001
# define ISA_INDEX_MAGIC_VALUE 0x001C0001
# define ISA_BITFIELD \
uintptr_t nonpointer : 1; \
uintptr_t has_assoc : 1; \
uintptr_t indexcls : 15; \
uintptr_t magic : 4; \
uintptr_t has_cxx_dtor : 1; \
uintptr_t weakly_referenced : 1; \
uintptr_t deallocating : 1; \
uintptr_t has_sidetable_rc : 1; \
uintptr_t extra_rc : 7
# define RC_ONE (1ULL<<25)
# define RC_HALF (1ULL<<6)
# else
# error unknown architecture for indexed isa
# endif
// SUPPORT_INDEXED_ISA
#endif
isa arm64参数详解
-
nonpointer: 0,代表普通的指针,存储着Class、Meta-Class对象的内存地址 1,代表优化过,使用位域存储更多的信息
-
has_assoc:是否有设置过关联对象,如果没有,释放时会更快
-
has_cxx_dtor:是否有C++的析构函数(.cxx_destruct),如果没有,释放时会更快
-
shiftcls:存储着Class、Meta-Class对象的内存地址信息
-
magic:用于在调试时分辨对象是否未完成初始化
-
weakly_referenced:是否有被弱引用指向过,如果没有,释放时会更快
-
deallocating:对象是否正在释放
-
extra_rc:表示该对象的引用计数值,实际上是引用计数值减 1,例如,如果对象的引用计数为 10,那么 extra_rc 为 9。如果引用计数大于 10,则需要使用到下面的 has_sidetable_rc。
-
has_sidetable_rc:当对象引用计数大于 10 时,则has_sidetable_rc 的值为 1,那么引用计数会存储在一个叫 SideTable 的类的属性中,这是一个散列表。
isa初始化
isa的初始化函数
inline void
objc_object::initIsa(Class cls, bool nonpointer, bool hasCxxDtor)
{
assert(!isTaggedPointer());
if (!nonpointer) {//代表普通的指针,存储着Class、Meta-Class对象的内存地址
isa.cls = cls;
} else {//代表优化过,使用位域存储更多的信息
assert(!DisableNonpointerIsa);
assert(!cls->instancesRequireRawIsa());
isa_t newisa(0);
#if SUPPORT_INDEXED_ISA
assert(cls->classArrayIndex() > 0);
newisa.bits = ISA_INDEX_MAGIC_VALUE;
// isa.magic is part of ISA_MAGIC_VALUE
// isa.nonpointer is part of ISA_MAGIC_VALUE
newisa.has_cxx_dtor = hasCxxDtor;
newisa.indexcls = (uintptr_t)cls->classArrayIndex();
#else
newisa.bits = ISA_MAGIC_VALUE;
// isa.magic is part of ISA_MAGIC_VALUE
// isa.nonpointer is part of ISA_MAGIC_VALUE
newisa.has_cxx_dtor = hasCxxDtor;
newisa.shiftcls = (uintptr_t)cls >> 3;
#endif
// This write must be performed in a single store in some cases
// (for example when realizing a class because other threads
// may simultaneously try to use the class).
// fixme use atomics here to guarantee single-store and to
// guarantee memory order w.r.t. the class index table
// ...but not too atomic because we don't want to hurt instantiation
isa = newisa;
}
}
isa的类调用alloc函数的时候执行了这段初始化函数。
class_createInstance -> _class_createInstanceFromZone ->obj-> initIsa(cls);
isa在初始化的时候将类的信息关联到isa中,也就是说新创建的出来的对象和类,通过isa关联了起来。
isa指向流程
通过上面isa的初始化,我们已经明白了,对象 isa 和类之间的关系了。 讲到isa的流程,那么我们就不得不把这个经典的流程图分享出来
Class objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes)
{
Class cls, meta;
。。。只留下关键部分
// Allocate new classes.
cls = alloc_class_for_subclass(superclass, extraBytes);
meta = alloc_class_for_subclass(superclass, extraBytes);
// fixme mangle the name if it looks swift-y?
objc_initializeClassPair_internal(superclass, name, cls, meta);
return cls;
}
在这里我们可以看到,创建新的类,除了需要一个cls,也就是我们需要的类,还有一个关键的参数meta,也就是我们通常所说的元类。
接下来我们通过objc_initializeClassPair_internal(superclass, name, cls, meta);这个函数来解析类和元类之间的关系。
这里我们先贴出initClassIsa的源码
inline void
objc_object::initClassIsa(Class cls)
{
if (DisableNonpointerIsa || cls->instancesRequireRawIsa()) {
initIsa(cls, false/*not nonpointer*/, false);
} else {
initIsa(cls, true/*nonpointer*/, false);
}
}
其内部调用的是我们上面提到的isa初始化函数initIsa,通过这个函数我们可以将类和元类关联起来。
static void objc_initializeClassPair_internal(Class superclass, const char *name, Class cls, Class meta)
{
....我们从中摘录出isa的相关部分
// Connect to superclasses and metaclasses
cls->initClassIsa(meta);//把类和元类关联起来
if (superclass) {
meta->initClassIsa(superclass->ISA()->ISA());//初始化元类的isa,取父类isa的isa,也就是父类元类的元类,即根元类
cls->superclass = superclass;
meta->superclass = superclass->ISA();//元类的父类是父类的isa,即继承与父类的元类
addSubclass(superclass, cls);
addSubclass(superclass->ISA(), meta);
} else {
meta->initClassIsa(meta);//如果没有父类,那就根类,OC中常见的根类即NSObject 根类的元类的isa指向根类的元类
cls->superclass = Nil;这个类没有父类
meta->superclass = cls;元类的父类就是这个类
addRootClass(cls);
addSubclass(cls, meta);
}
}
通过对上面代码的理解,我们可以得出和上面吻合的流程图。