类的加载过程
上一篇文章得到类值在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要实现的类previously为nil
变量
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;
}
- 如果有关联对象或父类有
rw加RW_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_class的bits - 然后递归实现 父类和元类
- 添加加一些标记
- 最后调用
methodizeClass