iOS - Runtime - Class的结构

文章目录

  • [iOS - Runtime - Class的结构](#iOS - Runtime - Class的结构)
    • 前言
    • [1. Class的结构](#1. Class的结构)
      • [1.1 Class的结构](#1.1 Class的结构)
        • [1.1.1 objc_class](#1.1.1 objc_class)
        • [1.1.2 class_rw_t](#1.1.2 class_rw_t)
        • [1.1.3 class_ro_t](#1.1.3 class_ro_t)
      • [1.2 class_rw_t和class_ro_t的区别](#1.2 class_rw_t和class_ro_t的区别)
      • [1.3 class_rw_t和class_ro_t的关系](#1.3 class_rw_t和class_ro_t的关系)
        • [1.3.1 分析关系](#1.3.1 分析关系)
        • [1.3.2 原因](#1.3.2 原因)
      • [1.4 method_t](#1.4 method_t)
        • [1.4.1 Type Encoding](#1.4.1 Type Encoding)
        • [1.4.2 types说明](#1.4.2 types说明)
          • [1.4.2.1 - (void)test](#1.4.2.1 - (void)test)
          • [1.4.2.2 - (void)test:(NSString *)name](#1.4.2.2 - (void)test:(NSString *)name)

iOS - Runtime - Class的结构

前言

1. Class的结构

前面我们学习OC对象的时候,了解了class类对象、meta-class元类对象

实际上,class类对象、meta-class元类对象底层结构体都是class元类对象可以认为是特殊的类对象。他们底层结构是一样的,只不过存储的内容有所区别

1.1 Class的结构

Class的结构如下图所示:

1.1.1 objc_class

里面存储了

  • isa
  • superclass
  • cache
  • bits

其中的bits& FAST_DATA_MASK位运算之后,拿到class_rw_tclass_rw_t里面的ro则是class_ro_t

1.1.2 class_rw_t
  • class_rw_t里面的methodspropertiesprotocols是二维数组,是可读可写的,包含了类的初始内容分类的内容
1.1.3 class_ro_t
  • class_ro_t里面的baseMethodListbaseProtocolsivarsbaseProperties是一维数组,是只读的,包含了类的初始内容

1.2 class_rw_t和class_ro_t的区别

对于他们里面的主要内容:

  1. class_rw_tmethodspropertiesprotocols
  2. class_ro_tbaseMethodListbaseProtocolsivarsbaseProperties

区别主要是:

  • class_rw_t的主要成员是二维数组class_ro_t的主要成员是一维数组
  • class_rw_t的主要成员是可读可写的,class_ro_t是只读的

1.3 class_rw_t和class_ro_t的关系

class_rw_tclass_ro_t里面的结构很像,但是class_ro_t的成员基本上带了base

1.3.1 分析关系

其实刚开始的时候不存在rw的,class里面的东西都保存在ro里面,bits取出来的其实是rorw是后面才生成的

因为rw是可读可写的,生成的时候,会把ro里面的东西合并进去,然后把rw设置为datacls->setData(rw),此时rw就替换了原本ro的位置,同时rw把ro属性指向原来的ro对象

1.3.2 原因

class_rw_t里面的数据基本上是二维数组,并且是可读可写。

我们知道分类的东西是runtime阶段才附加进去的,在将分类的东西合并到class里面的时候。

因此他们之间是相互配合的,class_ro_t先是存储了编译期间固定的东西,运行时一些动态的东西则是存入class_rw_tclass_rw_t在初始化前会将class_ro_t的东西先附加进去。于是class_rw_t里面就有完整的东西

1.4 method_t

  • method_t是对方法\ 函数的封装
  • IMP代表函数的具体实现
  • SEL代表方法\函数名,一般叫做选择器,底层结构跟char *类似
    1. 可以通过@selector()sel_registerName()获得
    2. 可以通过sel_getName()NSStringFromSelector()转成字符串
    3. 不同类相同名字的方法,所对应的方法选择器相同
  • types包含了函数返回值、参数编码的字符串
返回值 参数1 参数2 ... 参数n
1.4.1 Type Encoding

iOS中提供了一个叫做@encode的指令,可以将具体的类型表示成字符串编码

1.4.2 types说明

使用Xcode 12.5.1 iPhone(12.4)模拟器

1.4.2.1 - (void)test

方法- (void)test;对应的typesv16@0:8

  • - (void)test;实际上C语言函数为:- (void)test:(id)self _cmd:(SEL)_cmd,包含self_cmd两个参数

于是types表示如下表:

v 16 @ 0 : 8
void 无返回值 2个参数共16字节 1个参数:id类型 1个参数:从0字节开始 2个参数:SEL类型 2个参数:从8字节开始
1.4.2.2 - (void)test:(NSString *)name

test方法增加一个name参数,此时typesv24@0:8@16

types表示如下表:

于是types表示如下表:

v 24 @ 0 : 8 @ 16
void 无返回值 3个参数共24字节 1个参数:id类型 1个参数:从0字节开始 2个参数:SEL类型 2个参数:从8字节开始 3个参数:id类型 3个参数:从16字节开始

@oubijiexi

相关推荐
missmisslulu8 小时前
电容笔值得买吗?2024精选盘点推荐五大惊艳平替电容笔!
学习·ios·电脑·平板
GEEKVIP9 小时前
手机使用技巧:8 个 Android 锁屏移除工具 [解锁 Android]
android·macos·ios·智能手机·电脑·手机·iphone
GEEKVIP9 小时前
如何在 Windows 10 上恢复未保存/删除的 Word 文档
macos·ios·智能手机·电脑·word·笔记本电脑·iphone
奇客软件10 小时前
iPhone使用技巧:如何恢复变砖的 iPhone 或 iPad
数码相机·macos·ios·电脑·笔记本电脑·iphone·ipad
奇客软件1 天前
如何从相机的记忆棒(存储卡)中恢复丢失照片
深度学习·数码相机·ios·智能手机·电脑·笔记本电脑·iphone
GEEKVIP2 天前
如何修复变砖的手机并恢复丢失的数据
macos·ios·智能手机·word·手机·笔记本电脑·iphone
一丝晨光2 天前
继承、Lambda、Objective-C和Swift
开发语言·macos·ios·objective-c·swift·继承·lambda
GEEKVIP2 天前
iPhone/iPad技巧:如何解锁锁定的 iPhone 或 iPad
windows·macos·ios·智能手机·笔记本电脑·iphone·ipad
KWMax2 天前
RxSwift系列(二)操作符
ios·swift·rxswift
Mamong2 天前
Swift并发笔记
开发语言·ios·swift