IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> iOS开发底层之应用加载中 - 13 -> 正文阅读

[移动开发]iOS开发底层之应用加载中 - 13


本章内容描述

  1. 本章的源码依旧是在 objc 源码中。
  2. 类的实现 realizeClassWithoutSwift 重点方法
  3. 运行的主线为: Read_images -》realizeClassWithoutSwift -》 methodizeClass
  4. 懒加载与非懒加载
  5. 分类的创建

一、realizeClassWithoutSwift

  1. 下面源码只显示关键代码 ,一步一步探索类的实现
static Class realizeClassWithoutSwift(Class cls, Class previously)
{
// 上锁
    runtimeLock.assertLocked();
    
    class_rw_t *rw;
    Class supercls;
    Class metacls;

    if (!cls) return nil;
    if (cls->isRealized()) {
        validateAlreadyRealizedClass(cls);
        return cls;
    }
    ASSERT(cls == remapClass(cls));
    
    auto ro = (const class_ro_t *)cls->data(); //只得到地址
    auto isMeta = ro->flags & RO_META;
    if (ro->flags & RO_FUTURE) {
        rw = cls->data();
        ro = cls->data()->ro();
        ASSERT(!isMeta);
        cls->changeInfo(RW_REALIZED|RW_REALIZING, RW_FUTURE);
    } else {
        // Normal class. Allocate writeable class data.
        // 这里看出 rw其实就是ro复制过去的。 所以他们很相似
        // ro这里赋值给rw后就不会再动了
        rw = objc::zalloc<class_rw_t>();
        rw->set_ro(ro);
        rw->flags = RW_REALIZED|RW_REALIZING|isMeta;
        cls->setData(rw);
    }
    // 父类 ,元类的获取 
    // 类 、 isa的走位图
        supercls = realizeClassWithoutSwift(remapClass(cls->getSuperclass()), nil);
        metacls = realizeClassWithoutSwift(remapClass(cls->ISA()), nil);
       
    // 进行赋值   
    cls->setSuperclass(supercls);
    cls->initClassIsa(metacls);

    // Reconcile instance variable offsets / layout.
    // This may reallocate class_ro_t, updating our ro variable.
    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
    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 {
        addRootClass(cls);
    }

    // Attach categories
    methodizeClass(cls, previously);

    return cls;
}

二、methodizeClass

  1. 对象的方法列表进行处理的方法
static void methodizeClass(Class cls, Class previously)
{
    runtimeLock.assertLocked();

    bool isMeta = cls->isMetaClass();
    auto rw = cls->data();
    auto ro = rw->ro();
    auto rwe = rw->ext();
    // Install methods and properties that the class implements itself.
    method_list_t *list = ro->baseMethods();
    if (list) {
        // 1. 对方法列表的处理: 根据内存地址进行排序  具体算法在fixupMethodList方法中
        prepareMethodLists(cls, &list, 1, YES, isBundleClass(cls), nullptr);
        // 2. 把方法存放在 rwe 中。 
        if (rwe) rwe->methods.attachLists(&list, 1);
    }

    property_list_t *proplist = ro->baseProperties;
    if (rwe && proplist) {
        rwe->properties.attachLists(&proplist, 1);
    }

    protocol_list_t *protolist = ro->baseProtocols;
    if (rwe && protolist) {
        rwe->protocols.attachLists(&protolist, 1);
    }
    // Attach categories. 分类赋值
    if (previously) {
        if (isMeta) {
            objc::unattachedCategories.attachToClass(cls, previously,
                                                     ATTACH_METACLASS);
        } else {
            objc::unattachedCategories.attachToClass(cls, previously,
                                                     ATTACH_CLASS_AND_METACLASS);
        }
    }
    objc::unattachedCategories.attachToClass(cls, cls,
#endif
}

1. 扩展 read_images

  • 条件控制进行一次的加载
  • 修复预编译阶段的 @selector 的混乱情况
  • 错误混乱类的处理
  • 修复重映射一些没有被镜像文件加载进来的的类
  • 修复一些消息
  • 类中有协议的时候, readProtocol
  • 修复没有被加载的协议
  • 分类处理
  • 类的加载处理
  • 没有被处理的类,优化被侵犯的类

三、懒加载与非懒加载类的区别

当前类是否实现了load方法,实现了load方法就是非懒加载,反之就是懒加载

1.懒加载执行顺序

数据加载推迟到第一次消息的时候

  1. lookUpImpOrForward
  2. realizeClassMayBeSwiftMaybeRelock
  3. realizeClassWithoutSwift
  4. methodizeClass

2. 非懒加载的的执行顺序

map_images的时候回加载所有类的数据

  1. readClass
  2. _getObjc2NonlazyClassList
  3. realizeClassWithoutSwift
  4. methodizeClass

四. category 分类的介绍

  1. 底层也是个结构体
struct _category_t {
const char *name;
struct _class_t *cls;
const struct _method_list_t *instance_methods;
const struct _method_list_t  *class_methods;
const struct _protocol_list_t *protocols;
const struct _prop_list_t *properties; 
}
  1. 分类没有元类
  2. 源码路径 : attachToClass -》 attachCategories
  3. rwe内存分配源码:
    class_rw_ext_t *extAllocIfNeeded() {
        auto v = get_ro_or_rwe();
        if (fastpath(v.is<class_rw_ext_t *>())) {
            return v.get<class_rw_ext_t *>(&ro_or_rw_ext);
        } else {
            return extAlloc(v.get<const class_ro_t *>(&ro_or_rw_ext));
        }
    }
  1. rwe被alloc的时机: 可以搜索整个OBJC 源码工程 ,关键字 extAlloc。 会发现在:动态添加属性, 动态添加方法,添加协议,添加分类的时候才会被创建。

总结

1. ro 、rw 、rwe的区别?

类包含了:元类,父类, flags, method cache ,还有类本身,同时还拥有指向一片干净内存的指针(clean memory), 这就是Ro,加载到内存后,就不能再修改。
相对的,就存在dirty meomory,这就是rw, rw在程序运行时发生更改的内存,但是在实际应用中,类的使用量不多,这样就造成了内存浪费, 所以苹果设计出了 rwe,这样就会把rw中的方法,属性, 协议, 分类等都放入了rwe。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-22 13:39:10  更:2021-08-22 13:39:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 9:58:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码