iOS分类实现原理

iOS底层原理之Category分类实现原理解析 当我们在Category中重写现有类的方法时,Objective-C的运行时机制会将这个重写的方法添加到方法列表中,并将原始类中的方法替换为新的实现。通过Category,我们可以为现有的类添加新的方法,或者重写现有类的方法。当我们使用Category为一个类添加新的方法时,Objective-C的运行时机制会在方法列表中添加一个新的方法项,来表示这个新增的方法。综上所述,Category是Objective-C中一种强大的特性,它允许我们在不修改原始类的情况下为现有类添加新的方法或者重写现有类的方法。 阅读详情

iOS 分类底层是怎么实现的?
本文将分如下四个模块进行探究

  1. 分类的结构体
  2. 编译时的分类
  3. 分类的加载
  4. 总结

本文使用的runtime源码版本是 objc4 - 680
文中类与分类代码如下

//类
@interface Person : NSObject
@property (nonatomic ,copy) NSString *presonName;
@end

@implementation Person
- (void)doSomeThing{
    NSLog(@"Person");
}
@end
// 分类
@interface Person(categoryPerson)
@property (nonatomic ,copy) NSString *categoryPersonName;
@end

@implementation Person(categoryPerson)
- (void)doSomeThing{
    NSLog(@"categoryPerson");
}
@end

1.分类的结构体

struct _category_t {
    const char *name;//类名
    struct _class_t *cls;//类
    const struct _method_list_t *instance_methods;//category中所有给类添加的实例方法的列表(instanceMethods)
    const struct _method_list_t *class_methods;//category中所有添加的类方法的列表(classMethods)
    const struct _protocol_list_t *protocols;//category实现的所有协议的列表(protocols)
    const struct _prop_list_t *properties;//category中添加的所有属性(instanceProperties)
};

struct category_t {
    const char *name; // 类名
    classref_t cls;   // 分类所属的类
    struct method_list_t *instanceMethods;  // 实例方法列表
    struct method_list_t *classMethods;     // 类方法列表
    struct protocol_list_t *protocols;      // 遵循的协议列表
    struct property_list_t *instanceProperties; // 属性列表

    // 如果是元类,就返回类方法列表;否则返回实例方法列表
    method_list_t *methodsForMeta(bool isMeta) {
        if (isMeta) {
            return classMethods;
        } else {
            return instanceMethods;
        }
    }

    // 如果是元类,就返回 nil,因为元类没有属性;否则返回实例属性列表,但是...实例属性
    property_list_t *propertiesForMeta(bool isMeta) {
        if (isMeta) {
            return nil; // classProperties;
        } else {
            return instanceProperties;
        }
    }
};

2.编译时的分类

2.1分类的属性

// Person(categoryPerson) 属性列表
static struct /*_prop_list_t*/ {
    unsigned int entsize;  // sizeof(struct _prop_t)
    unsigned int count_of_properties;
    struct _prop_t prop_list[1];
} _OBJC_$_PROP_LIST_Person_$_categoryPerson __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_prop_t),
    1,
    {{"categoryPersonName","T@\"NSString\",C,N"}}
};

// Person 属性列表
static struct /*_prop_list_t*/ {
    unsigned int entsize;  // sizeof(struct _prop_t)
    unsigned int count_of_properties;
    struct _prop_t prop_list[1];
} _OBJC_$_PROP_LIST_Person __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_prop_t),
    1,
    {{"presonName","T@\"NSString\",C,N,V_presonName"}}
};

对比上述代码可以发现:在分类中可以声明属性,并且同样会生成一个 _prop_list_t 的结构体

2.2分类的实例变量?

// Person 实例变量列表

static struct /*_ivar_list_t*/ {
    unsigned int entsize;  // sizeof(struct _prop_t)
    unsigned int count;
    struct _ivar_t ivar_list[1];
} _OBJC_$_INSTANCE_VARIABLES_Person __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_ivar_t),
    1,
    {{(unsigned long int *)&OBJC_IVAR_$_Person$_presonName, "_presonName", "@\"NSString\"", 3, 8}}
};

因为 _category_t 这个结构体中并没有 _ivar_list_t
所以在编译时系统没有Person(categoryPerson) 没有生成类似的相应结构体,也没有生成 _categoryPersonName。

2.3分类的实例方法

// Person 实例方法结构体
static struct /*_method_list_t*/ {
    unsigned int entsize;  // sizeof(struct _objc_method)
    unsigned int method_count;
    struct _objc_method method_list[3];
} _OBJC_$_INSTANCE_METHODS_Person __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_objc_method),
    3,
    {{(struct objc_selector *)"doSomeThing", "v16@0:8", (void *)_I_Person_doSomeThing},
    {(struct objc_selector *)"presonName", "@16@0:8", (void *)_I_Person_presonName},
    {(struct objc_selector *)"setPresonName:", "v24@0:8@16", (void *)_I_Person_setPresonName_}}
};

// Person(categoryPerson )实例方法结构体
static struct /*_method_list_t*/ {
    unsigned int entsize;  // sizeof(struct _objc_method)
    unsigned int method_count;
    struct _objc_method method_list[1];
} _OBJC_$_CATEGORY_INSTANCE_METHODS_Person_$_categoryPerson __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_objc_method),
    1,
    {{(struct objc_selector *)"doSomeThing", "v16@0:8", (void *)_I_Person_categoryPerson_doSomeThing}}
};

对比上述方法可以看到:虽然分类可以声明属性,但是编译时,系统并没有生成分类属性的 get/set 方法,所以,这就是为什么分类要利用
runtime 动态添加属性,如何动态添加属性,有兴趣的同学可以查看下面文章 iOS分类中通过runtime添加动态属性

2.4分类的结构体

// Person(categoryPerson ) 结构体
static struct _category_t _OBJC_$_CATEGORY_Person_$_categoryPerson __attribute__ ((used, section ("__DATA,__objc_const"))) = 
{
    "Person",
    0, // &OBJC_CLASS_$_Person,
    (const struct _method_list_t *)&_OBJC_$_CATEGORY_INSTANCE_METHODS_Person_$_categoryPerson,
    0,
    0,
    (const struct _prop_list_t *)&_OBJC_$_PROP_LIST_Person_$_categoryPerson,
};

这是系统在编译时实例化 _category_t 生成的
_OBJC_$_CATEGORY_Person_$_categoryPerson

2.5分类数组

static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [1] __attribute__((used, section ("__DATA, __objc_catlist,regular,no_dead_strip")))= {
    &_OBJC_$_CATEGORY_Person_$_categoryPerson,
};

编译器最后生成了一个数组,数组的元素就是我们创建的各个分类,用来在运行时加载分类。

3.分类的加载

3.1加载分类调用栈

_objc_init
└──map_2_images
    └──map_images_nolock
        └──_read_images

分类加载的调用栈如上述

  • _objc_init 算是整个 objc4 的入口,进行了一些初始化操作,注册了镜像状态改变时的回调函数
  • map_2_images 主要是加锁并调用 map_images_nolock
  • map_images_nolock 在这个函数中,完成所有 class 的注册、fixup等工作,还有初始化自动释放池、初始化 side table 等工作并在函数后端调用了 _read_images
  • _read_images 方法干了很多苦力活,比如加载类、Protocol、Category,加载分类的代码就写在 _read_images 函数的尾部

该调用栈入口函数 void _objc_init(void) 在 objc-os.mm 中,有兴趣的同学可以去看看这些函数里都做了什么

3.2 _read_images 中加载分类的源码

加载分类的源码主要做了两件事

  • 把category的实例方法、协议以及属性添加到类上
  • 把category的类方法和协议添加到类的metaclass上

略去与本文无关的代码,得到如下代码

// 获取 镜像中的所有分类
category_t **catlist = _getObjc2CategoryList(hi, &count);
// 遍历 catlist
for (i = 0; i < count; i++) {
    category_t *cat = catlist[i];
    Class cls = remapClass(cat->cls);
    if (cat->instanceMethods ||  cat->protocols
        ||  cat->instanceProperties) 
    {
        addUnattachedCategoryForClass(cat, cls, hi);
        if (cls->isRealized()) {
            remethodizeClass(cls);
            classExists = YES; 
        }
    }
    if (cat->classMethods  ||  cat->protocols
        /* ||  cat->classProperties */)
    {
        addUnattachedCategoryForClass(cat, cls->ISA(), hi);
        if (cls->ISA()->isRealized()) {
            remethodizeClass(cls->ISA());
        }
    }
}

做上述事情主要用到是如下两个函数

  • addUnattachedCategoryForClass(cat, cls, hi) 为类添加未依附的分类
    执行过程伪代码:
    1.取得存储所有 unattached 分类的列表

    NXMapTable *cats = unattachedCategories();

    2.从 cats 列表中找倒 cls 对应的 unattached 分类的列表

    category_list *list = (category_list *)NXMapGet(cats, cls);

    3.将新来的分类 cat 添加刚刚开辟的位置上

    list->list[list->count++] = (locstamped_category_t){cat, catHeader};

    4.将新的 list 重新插入 cats 中,会覆盖老的 list

    NXMapInsert(cats, cls, list);

    执行完上述过程后,系统将这个分类放到了一个 cls 对应的 unattached 分类的 list 中(有点绕口....),这个 list 会在 remethodizeClass(cls) 方法用到

  • remethodizeClass(cls)
    执行过程伪代码:
    1.取得 cls 类的 unattached 的分类列表

    category_list *cats = unattachedCategoriesForClass(cls, false/*not realizing*/)

    2.将 unattached 的分类列表 attach 到 cls 类上

    attachCategories(cls, cats, true /* 清空方法缓存 flush caches*/);

    执行完上述过程后,系统就把category的实例方法、协议以及属性添加到类上

  • 最后再来看一下
    attachCategories(cls, cats, true /* 清空方法缓存 flush caches*/)内部的实现过程
    1.在堆上创建方法、属性、协议数组,用来存储分类的方法、属性、协议

    method_list_t **mlists = (method_list_t **)malloc(cats->count * sizeof(*mlists));
    property_list_t **proplists = (property_list_t **)malloc(cats->count * sizeof(*proplists));
    protocol_list_t **protolists = (protocol_list_t **)malloc(cats->count * sizeof(*protolists));

    2.遍历 cats ,取出各个分类的方法、属性、协议,并填充到上述代码创建的数组中

    int mcount = 0; // 记录方法的数量
    int propcount = 0; // 记录属性的数量
    int protocount = 0; // 记录协议的数量
    int i = cats->count; // 从后开始,保证先取最新的分类
    bool fromBundle = NO; // 记录是否是从 bundle 中取的
    while (i--) { // 从后往前遍历
      auto& entry = cats->list[i]; // 分类,locstamped_category_t 类型
      // 取出分类中的方法列表;如果是元类,取得的是类方法列表;否则取得的是实例方法列表
      method_list_t *mlist = entry.cat->methodsForMeta(isMeta);
      if (mlist) {
          mlists[mcount++] = mlist; // 将方法列表放入 mlists 方法列表数组中
          fromBundle |= entry.hi->isBundle(); // 分类的头部信息中存储了是否是 bundle,将其记住
      }
      // 取出分类中的属性列表,如果是元类,取得是nil
      property_list_t *proplist = entry.cat->propertiesForMeta(isMeta);
      if (proplist) {
          proplists[propcount++] = proplist; // 将属性列表放入 proplists 属性列表数组中
      }
      // 取出分类中遵循的协议列表
      protocol_list_t *protolist = entry.cat->protocols;
      if (protolist) {
          protolists[protocount++] = protolist; // 将协议列表放入 protolists 协议列表数组中
      }
    }

    3.取出 cls 的 class_rw_t 数据

    auto rw = cls->data();

    4.存储方法、属性、协议数组到 rw

    // 准备 mlists 中的方法
    prepareMethodLists(cls, mlists, mcount/*方法列表的数量*/, NO/*不是基本方法*/, fromBundle/*是否来自bundle*/);
    // 将新属性列表添加到 rw 中的属性列表数组中
    rw->properties.attachLists(proplists, propcount);
    // 释放 proplists
    free(proplists); // 释放 proplists
    // 将新协议列表添加到 rw 中的协议列表数组中
    rw->protocols.attachLists(protolists, protocount);
    // 释放 protolists
    free(protolists); // 释放 protolists
    // 将新协议列表添加到 rw 中的协议列表数组中
    rw->protocols.attachLists(protolists, protocount);
    // 释放 protolists
    free(protolists);

4.总结

至此,本文接近尾声
希望本文的读者能够了解到

  • 分类的结构体
  • 分类中是否能添加属性
  • 分类中是否有实例变量
  • 分类是如何 attach 到类上的

行笔简陋,如有问题,敬请指正



作者:CJS__
链接:http://www.jianshu.com/p/b7169a5a558e
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
stm32控制舵机_使用URT-1控制飞特舵机上手教程(SM40BL舵机为例) 使用URT-1控制飞特舵机上手教程(SM40BL舵机为例):1,参阅URT-1使用说明.pdf2, 材料清单:① URT-1驱动板② 连接驱动板与电脑的MINI USB 连接线③ 给舵机供电的电源④ 舵机与舵机连接线⑤ 杜邦线(可选)3,将URT-1驱动板与电脑连接4,安装驱动,参阅文件CH340驱动,检查设备管理器串口号。5,舵机连接URT-1驱动板,驱动板接电源,参考下图:6,打开FD软件进行... 阅读详情

相关推荐

DVWA靶场实战:从搭建到渗透测试的完整指南

本文详细介绍了DVWA靶场的搭建与渗透测试全流程,涵盖LAMP环境搭建、Docker部署及集成环境安装三种方式。通过SQL注入、文件上传漏洞等实战案例,帮助读者掌握Web安全测试技巧,并提供防御方案与进阶调优建议,是网络安全学习的实用指南。

weixin_28312391的博客 488

iOS分类底层实现原理小记

http://www.jianshu.com/p/b7169a5a558e OS 分类底层是怎么实现的?本文将分如下四个模块进行探究 分类的结构体 编译时的分类 分类的加载 总结 本文使用的runtime源码版本是 objc4 - 680文中类与分类代码如下 //类 @interface Person : NSObject @property (nonato...

diaoju3333的博客 352

vivado下ECO操作-不重新综合实现修改属性并生成.bit

ECO即engineer change order,即工程变更指令,可以对设计做局部小改动并只对改动部分重新布局布线并生成.bit。在一个工程动辄编译几个小时情况下,可以在调试中节省大量时间。比如我们在调试中,需要改变时钟占空比或者相位,需要改变寄存器初值等等,此时用ECO暂时改动,待验证后在重新编译无疑是最有效率的方法。 实现ECO通常有两种方式,一是通过vivado界面完成,另一种方法就是tcl脚本。所有的ECO操作都可以通过tcl操作完成,有的操作用vivado界面无法完成,只能通过tcl。以下主要

4656

多个category实现同一个方法调用的顺序

一​​​​​​准备工作: 搭建环境,新建category项目,添加A,B,C三个分类。 二 测试​​​​与结论: 1.主类和三个分类分别添加+ (void)load方法; 运行项目后,输出结果: 初步可以有以下结论:+load方法的优先级: 父类> 分类,那么分类的优先级是怎么样的呢? 我们调整分类的编译顺序: 结果发现:分类优先级为编译的顺序,从上到下...

小菜媛的博客 5146

SC8F073单片机串口通信保姆级教程:从寄存器配置到完整收发Demo(附避坑指南)

本文详细解析了SC8F073单片机串口通信的寄存器配置与调试技巧,涵盖TXSTA、RCSTA和SPBRG寄存器的逐位设置,提供精确的波特率计算方法和工业级抗干扰策略。通过完整的收发Demo和避坑指南,帮助开发者快速掌握底层串口通信技术,适用于工业控制等严苛环境。

weixin_33724046的博客 484

【自然语言处理(NLP)实战】LSTM网络实现中文文本情感分析(手把手与教学超详细)

在当今数字化时代,人们在社交媒体、评论平台以及各类在线交流中产生了海量的文本数据。这些数据蕴含着丰富的情感信息,从而成为了深入理解用户态度、市场趋势,甚至社会情绪的宝贵资源。自然语言处理(NLP)的发展为我们提供了强大的工具,使得对文本情感进行分析成为可能。在这个领域中,长短时记忆网络(LSTM)凭借其能够捕捉文本序列中长距离依赖关系的能力,成为了情感分析任务中的一项重要技术。通过详细的步骤和示例代码,深入了解如何处理中文文本数据、构建LSTM模型、进行训练和评估。

halo的博客 2万+

iOS原理篇(三) Category/分类/类别

一、Category的实现原理 Class Extension/扩展 简介 二、+load、+initialize、+alloc 、-init 加载过程及作用

zheshawanyier的博客 1369

遥感图像小白--2--图像分割

遥感图像分割基础入门

Mary的博客 4233

【iOS】分类,扩展与关联对象

上一篇章我们探究了类与对象的底层,这一篇我们探究一下分类,扩展与关联对象由于分类没有成员变量列表,所以无法添加成员变量。与此同时他有属性列表,但只会声明属性,不会去实现set与get方法。如果要在分类中使用属性就需要使用关联对象分类在运行时被整合到类中,扩展在编译时被整合到类中,因此分类中方法不实现不会报警,扩展会扩展常用于声明私有属性与方法如果分类中的方法与类中方法重名,分类中的方法会替代类中的方法。

weixin_72437555的博客 1366

麒麟信安3.3-6C电网版虚拟机安装避坑指南:从ISO下载到SSH配置全流程

本文提供麒麟信安3.3-6C电网版虚拟机的详细安装与配置指南。针对电力行业仿真测试需求,重点解析从ISO镜像获取、虚拟机环境准备、安装过程中的三大“雷区”(如多管理员密码逻辑、分区方案、网络配置)到首次启动后的网络、SSH及root策略配置的全流程避坑要点,帮助技术人员高效、安全地完成部署。

rainy的博客 853

YOLOv11改进 | Neck篇 | 双向特征金字塔网络BiFPN助力YOLOv11有效涨点

本文给大家带来的改进机制是BiFPN双向特征金字塔网络,其是一种特征融合层的结构,也就是我们本文改进YOLOv11模型中的Neck部分,它的主要思想是通过多层级的特征金字塔和双向信息传递来提高精度。本文给大家带来的结构可以让大家自行调节网络结构大小,同时能够达到一定的轻量化效果,为什么发BiFPN呢因为它算是YOLO系列改进中的常青树了,大家可以借鉴它的双向特征思想来创新自己的Neck结构本文的BiFPN通过yaml文件配置可以让大家自行调配其结构。

Snu77的博客 9095

iOS高级理论:分类和扩展

在 iOS 开发中,分类(Category)和扩展(Extension)是两种常用的机制,用于对现有类进行扩展和增强。它们可以为现有类添加新的方法、属性或协议,而无需修改原始类的源代码。

长沙火山 3019

哨兵1号回波数据(L0级)包格式解析与成像参数提取

提取哨兵1号数据包的辅助数据、回波数据、定标数据。matlab代码在文末

3124

iOS OC中分类Category实现原理

//联系人:石虎 QQ:1224614774 昵称:嗡嘛呢叭咪哄   一、概念   1.前言   category是Objective-C 2.0之后添加的语言特性,   category的主要作用是为已经存在的类添加方法。   2.设计思想   Objective-C 中的 Category 就是对装饰模式的一种具体实现。它的主要作用是在不改变原有类的前提下,动态地给这个类添加...

石虎 3392

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

iOS 消息推送原理及实现总结 分类: ios技术 ...

在实现消息推送之前先提及几个于推送相关概念,如下图: 1、 Provider:就是为指定IOS设备应用程序提供Push的服务器,(如果IOS设备的应用程序是客户端的话,那么Provider可以理解为服务端[消息的发起者]); 2、 APNS:Apple Push Notification Service[苹果消息推送服务器]; 3、 iPhone:用来接收APNS下发下来的消...

weixin_33955681的博客 84

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

iOS面试题(七)Objective-C语言 -分类的实现机制、原理(Runtime源码分析)

Objective-C语言 分类(什么是分类?分类的实现机制、原理是怎样的?我们应该怎样为一个分类提供实例变量呢?--涉及到第2点关联对象的考察) 关联对象(Runtime分析和查看分类和关联对象的实现机制、原理) 扩展、代理怎么使用(分类和扩展的区别在哪里?) KVO、KVC( KVO、KVC的实现机制、原理、包括涉及到了哪些设计思想) NSNotification(通知的实现机制...

ochenmengo的博客 1100

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【iOS开发-背景】关于按钮背景图片的拉伸

关于按钮背景图片拉伸与不拉伸的效果拉伸的效果: 不拉伸的效果 不拉伸的效果 拉伸的效果: 拉伸原理iOS开发中,有一个方法可以将图片按照指定的形式拉伸,拉伸方式为下图,一般拉伸部分都为0: 实现方式 新建一个UIImage的分类 为UIImage扩充一个方法+(UIImage )resizableImage:(NSString )imageName; 然后再按钮所在的ViewCon

沸沸腾的专栏 2722

ios中关于分类认知的一些总结

在IOS中,分类是一个极其便捷的代码管理方式,通过使用分类可以取得以下好处: 1.可以在.m文件中利用分类进行私有方法的添加,达到代码分类明确的作用 2.将代码进行分类,分解体积过于庞大的文件 3.将Framework的私有方法公开化 4.便于团队作业的代码整合   分类的特征是运行时决议,所谓运行时决议便是在代码进行运行时,才将对应的方法、属性、协议等真正添加到宿主类中,使用分类可以...

Horson19的博客 470

iOS OC 底层原理之 category、load、initialize

不能直接添加成员变量,但能通过runtime间接添加。property在category中只生成setter和getter方法声明。

xymspace 1767

【iOS】——分类,扩展以及关联对象

分类中没有成员列表,因此不能添加成员变量。但是有属性列表,可以添加属性的声明,但是不会合成set与get方法,如果要使用分类中的属性,需要使用关联对象。分类在运行的时候被整合到类中,扩展在编译的时候被整合到类中,因此分类中的方法不实现不会报错,扩展就会报错。扩展用于声明私有属性与方法。分类中的方法和类中的方法重名,分类中的方法会代替类中的方法。

qq_72437394的博客 1312

Objective-C 分类底层原理分析

1、什么是分类 iOS分类使用的场景就是把功能模块化,把一组类似的功能扩展出一个分类,便于代码的维护以及功能的分块 2、分类的底层结构 分类在iOS底层的数据结构如下: struct _category_t { const char *name; struct _class_t *cls; const struct _method_list_t *instance_metho...

风起云涌 468

iOS 底层探索篇 ——类的加载原理(下)

iOS 底层探索篇 ——类的加载原理(下)1. 为什么要有ro,rw,rwe2. cls->data()3. extAllocIfNeeded & attachCategories4.分类的懒加载类和分类都实现load类实现load和分类不实现load类不实现load和分类实现load类和分类都不实现load5. 4种不同情况下的分类加载类和分类都实现load 1. 为什么要有ro,rw,rwe ro属于cleanmemory,在编译即确定的内存空间,只读,加载后不会改变内容的空间 rw属

LinShunIos的博客 560

[iOS]类和对象的底层原探索

[iOS]类和对象的底层原探索

m0_74703932的博客 1629

【iOS】—— 分类、扩展和关联对象

一、分类与扩展的区别 1、category类别(分类) 专门用来给类添加新的方法。 不能给类添加成员属性,添加了成员属性,也无法取到。 【注意】:其实可以通过runtime给分类添加属性,即属性关联,重写setter、getter方法。 分类中用@property定义的变量,只会生成变量的setter、getter方法的声明,不能生成方法实现和带下划线的成员变量。 2、extension(类扩展) 可以说成是特殊的分类,也可称作匿名分类。 可以给类添加成员属性,但是是私有变量。 可以给类添加方法,也是

m0_55124878的博客 1047

iOS 底层探索篇 ——类的加载原理(中)

iOS 底层探索篇 ——类的加载原理(中) 上回说到readClass 里面给类加上了名字,那么ro,rw是在哪里加的呢?回到_read_images打上断点一点一点探究。 在remap classes 这里打上断点后运行,发现没有进去。 往下走,看到objc_msgSend_fixup,和类无关就跳过不看。继续往下走discover protocols也和类无关不看。在往下看到protocol references,也和类无关,继续往下走。discover categories,分类,继续跳过。继续往下

LinShunIos的博客 374
上一篇: iOS中保证线程安全的几种方式与性能对比
下一篇: iOS Block原理和内存中位置
直隶码农
博客等级 码龄19年 95粉丝 103原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值