OC底层探索(二十):类的实现<上>

330 阅读2分钟

类的加载过程

上一篇文章得到类值在realizeClassWithoutSwift方法是实现的

非懒加载

  • 程序启动 dyld_start -> dispatch_init-> libsystem_init -> objc_init
  • 然后到注册_dyld_objc_notify_register(&map_images, load_images, unmap_image)
  • 然后 map_imges -> read_images
  • readeImages中,如果类实现的+load方法,就是非懒加载的类
  • 懒加载类就会走realizeClassWithoutSwift实现该类

懒加载

  • 当类或类的实例调用方法时候,也就是发送消息objc_msgSend的时候
  • 当前类在缓存中没有找到,就会走慢速查找流程lookUpImpOrForward
  • 会判断类有没有实现,没有实现就会走realizeAndInitializeIfNeeded_locked
  • 然后调用realizeClassMaybeSwiftAndLeaveLocked
  • 在调用realizeClassMaybeSwiftMaybeRelock
  • 最后调用realizeClassWithoutSwift

realizeClassWithoutSwift 分析

static Class realizeClassWithoutSwift(Class cls, Class previously)

参数

  • cls 要实现的类
  • previouslynil

变量

class_rw_t *rw; // 也就是 bits->data()
Class supercls; // 父类
Class metacls; // 元类

主要逻辑

auto ro = (const class_ro_t *)cls->data();
  • class_data_bits_t bits, bits->data()中取出rw,强转成ro
  • 因为此时类是从mach-o读取的,所以只有clean memory -> ro
  • 这种直接强转是在llvm底层实现的,也就是编译时
rw = objc::zalloc<class_rw_t>();
rw->set_ro(ro);
rw->flags = RW_REALIZED|RW_REALIZING|isMeta;
cls->setData(rw);
  • 创建rw
  • 然后将ro复制一个给rw
  • 然后rw添加以实现标记
  • 在将rw赋值给给bits
cls->cache.initializeToEmptyOrPreoptimizedInDisguise();
  • 初始实话空的cache_t
if (isMeta) cls->cache.setBit(FAST_CACHE_META);
  • 如果是元类,cache添加元类标记

    supercls = realizeClassWithoutSwift(remapClass(cls->getSuperclass()), nil);
    metacls = realizeClassWithoutSwift(remapClass(cls->ISA()), nil);
  • 递归实现 父类和元类
// 更新父类和元类
cls->setSuperclass(supercls);
cls->initClassIsa(metacls);
  • objc_class结构体中的 superclass 赋值
  • 更新类的isa,也就指向元类
cls->setInstanceSize(ro->instanceSize);
  • 是对cache_t_flags进行赋值
  • 加了FAST_CACHE_ALLOC_MASK标记
// 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();
        }
    }
  • 如果有c++构造函数或析构函数cache缓存FAST_CACHE_HAS_CXX_DTOR 标记
  • 如果只有 析构函数没有构造函数cache缓存FAST_CACHE_HAS_CXX_CTOR标记
if ((ro->flags & RO_FORBIDS_ASSOCIATED_OBJECTS) ||
     (supercls && supercls->forbidsAssociatedObjects()))
    {
        rw->flags |= RW_FORBIDS_ASSOCIATED_OBJECTS;
    }
  • 如果有关联对象或父类有
  • rwRW_FORBIDS_ASSOCIATED_OBJECTS标记
// Connect this class to its superclass's subclass lists
    if (supercls) {
        addSubclass(supercls, cls);
    } else {
        addRootClass(cls);
    }
  • 如果是父类,将子类的nextSiblingClass赋值为子类firstSubclass,
  • 再将父类的firstSubclass 赋值为subcls
  • 所以父类的firstSubclass其实就是最后一个子类,是一个链表结构
methodizeClass(cls, previously);
  • 重点下一篇文章单独讲

总结

  • 同懒加载或非懒加载两种实现类
  • 主要是从 mach-o得去 ro, 然后开辟 rw,将ro复制一份给rw,在将rw,赋值给objc_classbits
  • 然后递归实现 父类和元类
  • 添加加一些标记
  • 最后调用methodizeClass