【iOS底层实验室】图解Class的实现与初始化

938 阅读3分钟

Hi 👋

My apps

-扫雷Elic 无尽天梯梦见账本
类型游戏财务
AppStoreElicUmemi

前言

在上一文中【Lawliet玩iOS源码】runtime-objc_msgSend中我们有遇到这样一个重要的流程

cls = realizeAndInitializeIfNeeded_locked(inst, cls, behavior & LOOKUP_INITIALIZE);

本文就将对类的实现与初始化,结合源码作深入探究。

/***********************************************************************
* realizeAndInitializeIfNeeded_locked
如果类未实现就实现,如果未初始化就初始化
inst:是cls或者其子类的一个实例对象,或者nil
cls:需要初始化或者实现的类
initialize:true会初始化class,false跳过初始化
**********************************************************************/
static Class
realizeAndInitializeIfNeeded_locked(id inst, Class cls, bool initialize)
{
    runtimeLock.assertLocked();
    if (slowpath(!cls->isRealized())) {
        cls = realizeClassMaybeSwiftAndLeaveLocked(cls, runtimeLock);
    }

    if (slowpath(initialize && !cls->isInitialized())) {
        cls = initializeAndLeaveLocked(cls, inst, runtimeLock);
    }
    return cls;
}

本文基于 objc4-818.2源码

一、实现初始化的区别

这里你肯定和我一样有疑问:

  • 初始化我大概知道是啥,实现是个什么鬼?有什么区别?

1.1 isRealized()

bool isRealized() const {
    return !isStubClass() && (data()->flags & RW_REALIZED);
}

实际是判断当前类的class_rw_t *data()是否存在,及是否有标志位RW_REALIZED

1.2 isInitialized()

bool isInitialized() {
    return getMeta()->data()->flags & RW_INITIALIZED;
}

实际是判断metaClass的class_rw_t *data()是否存在,及是否有标志位RW_INITIALIZED

一、实现类:realizeClassMaybeSwiftAndLeaveLocked

流程图

搭配源码及注释食用更加

iOS底层-类的实现.png

1.1 实现OC类

static Class realizeClassWithoutSwift(Class cls, Class previously)
{
    runtimeLock.assertLocked();

    class_rw_t *rw;
    Class supercls;
    Class metacls;

    if (!cls) return nil;
    if (cls->isRealized()) {
        // 已经实现了的话,验证一下没问题就return
        validateAlreadyRealizedClass(cls);
        return cls;
    }
    ASSERT(cls == remapClass(cls));

    // fixme verify class is not in an un-dlopened part of the shared cache?
    auto ro = (const class_ro_t *)cls->data();
    // 是否是元类
    auto isMeta = ro->flags & RO_META;
    
    if (ro->flags & RO_FUTURE) {
        // TODO: 不太知道这个是啥意思
        // This was a future class. rw data is already allocated.
        rw = cls->data();
        ro = cls->data()->ro();
        ASSERT(!isMeta);
        cls->changeInfo(RW_REALIZED|RW_REALIZING, RW_FUTURE);
    } else {
        // 一般Class。创建rw
        // Normal class. Allocate writeable class data.
        rw = objc::zalloc<class_rw_t>();
        // 设置ro
        rw->set_ro(ro);
        // 设置标志位
        rw->flags = RW_REALIZED|RW_REALIZING|isMeta;
        // 设置rw
        cls->setData(rw);
    }

    // 创建 cache
    cls->cache.initializeToEmptyOrPreoptimizedInDisguise();

#if FAST_CACHE_META
    if (isMeta) cls->cache.setBit(FAST_CACHE_META);
#endif

    /**
    选取在Class数组中的下标
    有个全局变量 objc_indexed_classes_count会递增
    全局数组用来保存Class Class objc_indexed_classes[1] = { nil };

    放入 objc_indexed_classes 是在
     */
    cls->chooseClassArrayIndex();

。。。
    
    // 父类
    supercls = realizeClassWithoutSwift(remapClass(cls->getSuperclass()), nil);
    // 元类
    metacls = realizeClassWithoutSwift(remapClass(cls->ISA()), nil);

#if SUPPORT_NONPOINTER_ISA
    。。。
// SUPPORT_NONPOINTER_ISA
#endif

    // Update superclass and metaclass in case of remapping
    // 设置父类
    cls->setSuperclass(supercls);
    // 设置类的ISA为metaClass
    cls->initClassIsa(metacls);

    // Reconcile instance variable offsets / layout.
    // This may reallocate class_ro_t, updating our ro variable.
    /**
     存在父类并且不是元类
     调整成员变量偏移量/布局,可能会重新创建 ro,并更新成员变量
     */
    if (supercls  &&  !isMeta) reconcileInstanceVariables(cls, supercls, ro);

    // Set fastInstanceSize if it wasn't set already.
    cls->setInstanceSize(ro->instanceSize);

    // Copy some flags from ro to rw
    // 将一些标志位从ro复制到rw
    if (ro->flags & RO_HAS_CXX_STRUCTORS) {
        cls->setHasCxxDtor();
        if (! (ro->flags & RO_HAS_CXX_DTOR_ONLY)) {
            cls->setHasCxxCtor();
        }
    }
    
    // Propagate the associated objects forbidden flag from ro or from
    // the superclass.
    if ((ro->flags & RO_FORBIDS_ASSOCIATED_OBJECTS) ||
        (supercls && supercls->forbidsAssociatedObjects()))
    {
        rw->flags |= RW_FORBIDS_ASSOCIATED_OBJECTS;
    }

    // Connect this class to its superclass's subclass lists
    if (supercls) {
        // 如果存在父类,添加到其子类列表中
        addSubclass(supercls, cls);
    } else {
        /**
         设置根类:全局变量 _firstRealizedClass
         
         ***********************************************************************
         * _firstRealizedClass
         * The root of all realized classes
         **********************************************************************
         static Class _firstRealizedClass = nil;
         
         */
        addRootClass(cls);
    }

    // Attach categories
    /***********************************************************************
    添加分类
    * Fixes up cls's method list, protocol list, and property list.
    **********************************************************************/
    methodizeClass(cls, previously);

    return cls;
}

1.2 实现Swift类

  • 注意点
    • Metaclasses never have a Swift initializer.
    • Root classes never have a Swift initializer.
    • (These two together avoid initialization order problems at the root.)
      • 这两条避免了初始化的顺序错乱的问题
    • 没有initializer的Swift类也不存在拥有initializer的父类
      • realizeClassWithoutSwift()内无须扫描父类
static Class realizeSwiftClass(Class cls)
{
。。。

    if (auto init = cls->swiftMetadataInitializer()) {
        // 有Swift元数据初始化方法
        。。。
        Class newcls = init(cls, nil);

        if (cls != newcls) {
            mutex_locker_t lock(runtimeLock);
            addRemappedClass(cls, newcls);
        }
        return newcls;
    }
    else {
        // 没有Swift初始化方法,直接调用OC的
        mutex_locker_t lock(runtimeLock);
        return realizeClassWithoutSwift(cls, nil);
    }
}

二、初始化类:initializeAndLeaveLocked

相比Realize的流程,初始化的流程相对简单。我画了个流程图。

iOS底层-类的初始化.png

三、总结

  • Realize
    • 主要完成类的基础结构的搭建
      • ISA链继承链rwro
  • Initialize
    • 找到非元类的Class
    • 标志位处理
    • +initialize方法调用