一,苹果开源源码汇总: https://opensource.apple.com
这个地址用的更直接 https://opensource.apple.com/tarballs/
二,下载最新的objc源码,找到_class_createInstanceFromZone方法,就是alloc主要做的事情
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone,
intconstruct_flags =OBJECT_CONSTRUCT_NONE,
boolcxxConstruct =true,
size_t*outAllocatedSize =nil)
{
ASSERT(cls->isRealized());
// Read class's info bits all at once for performance
boolhasCxxCtor = cxxConstruct && cls->hasCxxCtor();
boolhasCxxDtor = cls->hasCxxDtor();
boolfast = cls->canAllocNonpointer();
size_tsize;
//1,计算对象需要分配多少空间
size = cls->instanceSize(extraBytes);
if(outAllocatedSize) *outAllocatedSize = size;
idobj;
if(zone) {
obj = (id)malloc_zone_calloc((malloc_zone_t*)zone,1, size);
}else{
// 2,alloc 向系统申请开辟内存的地方,返回地址指针
obj = (id)calloc(1, size);
}
if(slowpath(!obj)) {
if(construct_flags &OBJECT_CONSTRUCT_CALL_BADALLOC) {
return _objc_callBadAllocHandler(cls);
}
returnnil;
}
if(!zone && fast) {
//3,关联到相应的类
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)) {
returnobj;
}
construct_flags |=OBJECT_CONSTRUCT_FREE_ONFAILURE;
returnobject_cxxConstructFromClass(obj, cls, construct_flags);
}
三,alloc 底层主要做了3件事情
1,计算对象需要分配多少空间,16字节对齐
cls->instanceSize(extraBytes)
size_t instanceSize(size_t extraBytes) const {
if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
return cache.fastInstanceSize(extraBytes);
}
size_t size = alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16 bytes.
// 16字节对齐,不够16字节,默认给16字节
if (size < 16) size = 16;
return size;
}
size_t fastInstanceSize(size_t extra) const
{
ASSERT(hasFastInstanceSize(extra));
if (__builtin_constant_p(extra) && extra == 0) {
return _flags & FAST_CACHE_ALLOC_MASK16;
} else {
size_t size = _flags & FAST_CACHE_ALLOC_MASK;
// remove the FAST_CACHE_ALLOC_DELTA16 that was added
// by setFastInstanceSize
return align16(size + extra - FAST_CACHE_ALLOC_DELTA16);
}
}
这个函数是16字节对齐的算法,x + 15 与上 15取反
例如:x = 12, 12 + 15 = 27
0000 1100 :12
0000 1111 : 15
0001 1011 := 27
1111 0000 :与15取反
0001 0000 := 16
static inline size_t align16(size_t x) {
return (x + size_t(15)) & ~size_t(15);
}
2,向系统申请开辟内存,返回地址指针
calloc
3,关联到相应的类
obj->initInstanceIsa
四,init 其实只是返回 (id)self
init : return (id)self; 是一个构造方法,一种工厂设计模式
网友评论