(杂记)iOS底层:类的加载流程

942 阅读1分钟

整个程序有两个表保存类:gdb_objc_realized_classes 和 allocatedClasses

gdb_objc_realized_classes:是全部从Maco里面加载的类

allocatedClasses:已经从Maco中加载到内存中的类

加载流程如下:

1 _objc_init

2 map_images

3 _read_images

3.1 readClass

以下代码基本是不走的!!

if (Class newCls = popFutureNamedClass(mangledName)) {
        // This name was previously allocated as a future class.
        // Copy objc_class to future class's struct.
        // Preserve future's rw data block.
        
        if (newCls->isAnySwift()) {
            _objc_fatal("Can't complete future class request for '%s' "
                        "because the real class is too big.", 
                        cls->nameForLogging());
        }
        
        class_rw_t *rw = newCls->data();
        const class_ro_t *old_ro = rw->ro;
        memcpy(newCls, cls, sizeof(objc_class));
        rw->ro = (class_ro_t *)newCls->data();
        newCls->setData(rw);
        freeIfMutable((char *)old_ro->name);
        free((void *)old_ro);

        addRemappedClass(cls, newCls);
        
        replacing = cls;
        cls = newCls;
    }

3.1.1 addNamedClass(cls, mangledName, replacing);

3.1.1.1 NXMapInsert(gdb_objc_realized_classes, name, cls);

gdb_objc_realized_classes

3.1.2 addClassTableEntry(cls);

allocatedClasses

3.1.2.1 allocatedClasses.insert

3.2 如果是非懒加载类 :realizeClassWithoutSwift

懒加载类会在方法调用的时候生成

IMP lookUpImpOrForward(Class cls, SEL sel, id inst, 
                       bool initialize, bool cache, bool resolver)
{
    if (!cls->isRealized()) {
        cls = realizeClassMaybeSwiftAndLeaveLocked(cls, runtimeLock);
    }
}

3.2.1 读取ro、创建rw、赋值ro\rw

ro = (const class_ro_t *)cls->data();
rw = (class_rw_t *)calloc(sizeof(class_rw_t), 1);
rw->ro = ro;
rw->flags = RW_REALIZED|RW_REALIZING;
cls->setData(rw);

3.2.2 实现metacls和supercls(递归)

 supercls = realizeClassWithoutSwift(remapClass(cls->superclass), nil);
 metacls = realizeClassWithoutSwift(remapClass(cls->ISA()), nil);
 
 出口为NSObject.superClass = nil

3.2.3 赋值metacls和supercls

 cls->superclass = supercls;
 cls->initClassIsa(metacls);

3.2.4 反向赋值superClass,实现双向链表结构

    if (supercls) {
        addSubclass(supercls, cls);
    } else {
        addRootClass(cls);
    }

3.2.5 methodizeClass

method_list_t *list = ro->baseMethods();
    if (list) {
        prepareMethodLists(cls, &list, 1, YES, isBundleClass(cls));
        rw->methods.attachLists(&list, 1);
    }
property_list_t *proplist = ro->baseProperties;
    if (proplist) {
        rw->properties.attachLists(&proplist, 1);
    }

protocol_list_t *protolist = ro->baseProtocols;
    if (protolist) {
        rw->protocols.attachLists(&protolist, 1);
    }

3.2.5.1 attachLists

attachLists