1. alloc
- (id)alloc { return _objc_rootAlloc(self); }
在 alloc 中实际调用了 _objc_rootAlloc 的方法,并把自己作为参数传入方法中。
2. _objc_rootAlloc
id _objc_rootAlloc(Class cls) { return callAlloc(cls, false/checkNil/, true/allocWithZone/); }
在_objc_rootAlloc 实际调用了 callAlloc 方法,并传入三个参数
- 对象的class
- 是否checkNil
- 以及是否allocWithZone
3. callAlloc
static ALWAYS_INLINE id
callAlloc(Class cls, bool checkNil, bool allocWithZone=false) { #if OBJC2 if (slowpath(checkNil && !cls)) return nil; if (fastpath(!cls->ISA()->hasCustomAWZ())) { return _objc_rootAllocWithZone(cls, nil); } #endif
// No shortcuts available.
if (allocWithZone) {
return ((id(*)(id, SEL, struct _NSZone *))objc_msgSend)(cls, @selector(allocWithZone:), nil);
}
return ((id(*)(id, SEL))objc_msgSend)(cls, @selector(alloc));
} 在 callAlloc 中,
- 如果编译器处于不优化模式,并且checkNil 为true 以及 cls 不为空的情况下,返回空。
- 如果编译器处于优化模式,并且cls没有自定义的allocWithZone,没有的话就调用,_objc_rootAllocWithZone方法,
- 如果编译器有自定义的allocWithZone,则调用自定义的allocWithZone
4. _objc_rootAllocWithZone
id _objc_rootAllocWithZone(Class cls, malloc_zone_t *zone __unused) { // allocWithZone under OBJC2 ignores the zone parameter return _class_createInstanceFromZone(cls, 0, nil, OBJECT_CONSTRUCT_CALL_BADALLOC); }
这里调用 _class_createInstanceFromZone方法
5. _class_createInstanceFromZone
static ALWAYS_INLINE id _class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone, int construct_flags = OBJECT_CONSTRUCT_NONE, bool cxxConstruct = true, size_t *outAllocatedSize = nil) { ASSERT(cls->isRealized());
// Read class's info bits all at once for performance
bool hasCxxCtor = cxxConstruct && cls->hasCxxCtor();
bool hasCxxDtor = cls->hasCxxDtor();
bool fast = cls->canAllocNonpointer();
size_t size;
size = cls->instanceSize(extraBytes);
if (outAllocatedSize) *outAllocatedSize = size;
id obj;
if (zone) {
obj = (id)malloc_zone_calloc((malloc_zone_t *)zone, 1, size);
} else {
obj = (id)calloc(1, size);
}
if (slowpath(!obj)) {
if (construct_flags & OBJECT_CONSTRUCT_CALL_BADALLOC) {
return _objc_callBadAllocHandler(cls);
}
return nil;
}
if (!zone && fast) {
obj->initInstanceIsa(cls, hasCxxDtor);
} else {
// Use raw pointer isa on the assumption that they might be
// doing something weird with the zone or RR.
obj->initIsa(cls);
}
if (fastpath(!hasCxxCtor)) {
return obj;
}
construct_flags |= OBJECT_CONSTRUCT_FREE_ONFAILURE;
return object_cxxConstructFromClass(obj, cls, construct_flags);
}
在这个方法中
- 声明 obj 时候(id obj)会有一个地址,系统会分配一个脏地址。
- size = cls->instanceSize(extraBytes); ,这个决定了开辟内存的大小,大小由成员变量决定,如果小于16则返回16。如果大于16,需要用字节对齐,返回8的倍数。
- 在calloc 之后,会申请内存,并将地址返回替换掉obj的脏地址,此时地址还未绑定类,关联类的是isa。
- 在 obj->initInstanceIsa(cls, hasCxxDtor); 之后,地址绑定类