+ (id)alloc {
return _objc_rootAlloc(self);
}
id _objc_rootAlloc(Class cls)
{
return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);
}
static ALWAYS_INLINE id
callAlloc(Class cls, bool checkNil, bool allocWithZone=false)
{
//This command is to check (checkNil && !cls)'s result which tell complier the result is more possible to be false;
if (slowpath(checkNil && !cls)) return nil;
#if __OBJC2__
// hasCustomAWZ() method means class or superclass has default alloc/allocWithZone: implementation, note this is is stored in the metaclass
if (fastpath(!cls->ISA()->hasCustomAWZ())) {
// FAST_ALLOC means
// FAST_HAS_CXX_CTOR is set
// FAST_REQUIRES_RAW_ISA is not set
// FAST_SHIFTED_SIZE is not zero
// FAST_ALLOC does NOT check FAST_HAS_DEFAULT_AWZ because that bit is stored on the metaclass.
if (fastpath(cls->canAllocFast())) {
bool dtor = cls->hasCxxDtor();
id obj = (id)calloc(1, cls->bits.fastInstanceSize());
if (slowpath(!obj)) return callBadAllocHandler(cls);
obj->initInstanceIsa(cls, dtor);
return obj;
}
else {
// Has ctor or raw isa or something. Use the slower path.
id obj = class_createInstance(cls, 0);
if (slowpath(!obj)) return callBadAllocHandler(cls);
return obj;
}
}
#endif
if (allocWithZone) return [cls allocWithZone:nil];
return [cls alloc];
}
//The slow Path: class_createInstance
//The fast path: initInstanceIsa, return value type is objc_object;
inline void
objc_object::initInstanceIsa(Class cls, bool hasCxxDtor)
{
assert(!cls->instancesRequireRawIsa());
assert(hasCxxDtor == cls->hasCxxDtor());
initIsa(cls, true, hasCxxDtor);
}
//Here is the struct of objc_object
struct objc_object {
private:
isa_t isa;
//other methods
}