1.1.对象原理探究-alloc流程

78 阅读1分钟

##1.alloc流程分析图 截屏2019-12-2523.15.35.png 截屏2019-12-2523.15.43.png

##2.alloc 调试相关断点和方法

(1)
int main(int argc, const char * argv[]) {
    @autoreleasepool {
       
        LGPerson *person = [LGPerson alloc]; //断点位置
        NSLog(@"%@",person);
    
    }
    return 0;
}
(2)
+ (id)alloc {
    return _objc_rootAlloc(self); //断点位置
}
(3)
id 
_objc_rootAlloc(Class cls)
{
    return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);//断点位置
}
(4)
// Call [cls alloc] or [cls allocWithZone:nil], with appropriate 
// shortcutting optimizations.
static ALWAYS_INLINE id
callAlloc(Class cls, bool checkNil, bool allocWithZone=false)
{
    if (slowpath(checkNil && !cls)) return nil;

#if __OBJC2__
    if (fastpath(!cls->ISA()->hasCustomAWZ())) {
        // No alloc/allocWithZone implementation. Go straight to the allocator.
        // fixme store hasCustomAWZ in the non-meta class and 
        // add it to canAllocFast's summary
        if (fastpath(cls->canAllocFast())) {
            // No ctors, raw isa, etc. Go straight to the metal.
            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

    // No shortcuts available.
    if (allocWithZone) return [cls allocWithZone:nil];
    return [cls alloc];
}
(5)
id 
class_createInstance(Class cls, size_t extraBytes)
{
    return _class_createInstanceFromZone(cls, extraBytes, nil);//断点位置
}
(6)
static __attribute__((always_inline)) 
id
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone, 
                              bool cxxConstruct = true, 
                              size_t *outAllocatedSize = nil)
{
    if (!cls) return nil;

    assert(cls->isRealized());

    // Read class's info bits all at once for performance
    bool hasCxxCtor = cls->hasCxxCtor();
    bool hasCxxDtor = cls->hasCxxDtor();
    bool fast = cls->canAllocNonpointer();

    size_t size = cls->instanceSize(extraBytes);
    if (outAllocatedSize) *outAllocatedSize = size;

    id obj;
    if (!zone  &&  fast) {
        obj = (id)calloc(1, size); //断点位置:这里calloc开辟空间
        if (!obj) return nil;
        obj->initInstanceIsa(cls, hasCxxDtor);
    } 
    else {
        if (zone) {
            obj = (id)malloc_zone_calloc ((malloc_zone_t *)zone, 1, size);
        } else {
            obj = (id)calloc(1, size);
        }
        if (!obj) return nil;

        // Use raw pointer isa on the assumption that they might be 
        // doing something weird with the zone or RR.
        obj->initIsa(cls);
    }

    if (cxxConstruct && hasCxxCtor) {
        obj = _objc_constructOrFree(obj, cls);
    }

    return obj;
}
(7).第(6)需要开辟空间,所以需要开辟空间的大小,所以从
size_t size = cls->instanceSize(extraBytes); 
研究:
 size_t instanceSize(size_t extraBytes) {
        size_t size = alignedInstanceSize() + extraBytes;//断点位置
        // CF requires all objects be at least 16 bytes.
        if (size < 16) size = 16;
        return size;
    }
(8).此处对齐字节
    uint32_t alignedInstanceSize() {
        return word_align(unalignedInstanceSize());//断点位置
    }
(9). 所以是8字节对齐(在64位下)
static inline uint32_t word_align(uint32_t x) {
    // 7+8 = 15
    // 0000 1111
    // 0000 1000
    //&
    // 1111 1000 ~7
    // 0000 1000 8
    
    // 0000 0111
    //
    // x + 7
    // 8
    // 8 二阶
    // (x + 7) >> 3 << 3
    return (x + WORD_MASK) & ~WORD_MASK;
}

开辟空间的大小有了以后,就需要初始化isa,这个下边在研究

##3.附上此图,可以研究下: alloc流程图 截屏2020-01-21上午9.47.33.png