Objecgtive-C学习实例对象,类对象, 元类对象与 isa指针

文章目录

  • OC对象的本质
  • [实例对象, 类对象, 元类的关系](#实例对象, 类对象, 元类的关系)
    • isa指针概念
      • isa的三条链
        • [第一条: 实例->类对象](#第一条: 实例->类对象)
        • [第二条 类对象 -> 元类](#第二条 类对象 -> 元类)
        • [第三条 元类 -> 根元类 -> 自己](#第三条 元类 -> 根元类 -> 自己)
      • [isa 完整链路图](#isa 完整链路图)
    • 获取元类的方法

OC对象的本质

oc的对象, 类, 主要是基于结构体去实现的

所有的OC对象都继承自NSObject, 类主要是基于结构体去实现的

objc 复制代码
// 类的结构体
struct NSObject_IMPL {
    Class isa; // Class是一个结构体类型, isa是一个结构体指针
}

继承自NSObject 的对象结构大致是, 这是一个继承自NSobject 的对象的Student, (被添加了name 和 age 两个属性)

objc 复制代码
struct Struct_IMPL {
    struct NSObject_IMPL NSobject_IVARS; (Class class) 
    int _age; 
    NSString* _name; 
}

OC的实例对象, 类对象. 元类对象

OC主要包括了3种对象

  1. 实例对象
  2. 类对象
  3. 元类对象

类对象

实例对象就是通过类 alloc 出来的对象 , 每一次调用 alloc 都会产生一个新的instance对象

  1. isa指针
  2. 其他成员变量

类对象

通过实例对象的class方法或类的class方法获取到类对象, 每个类在内存中有且只有一个class 对象

  1. isa指针
  2. superclass指针
  3. 类的属性信息 (@property)
  4. 类的对象方法信息
  5. 类的协议信息
  6. 类的成员变量信息

元类对象

每个类在内存中有且只有一个 元类对象 (meta-class)

  1. isa指针
  2. superclass指针
  3. 类的方法信息

实例对象, 类对象, 元类的关系

在 Objective-C 中,一切皆对象:

  • 普通类对象 :比如 [NSObject class] 获取的是 NSObject 的类对象,用于创建实例([[NSObject alloc] init])。
  • 元类 (Meta Class) :是类对象的 "类",专门存储类方法(+ 开头的方法)的地方。每个类都有且仅有一个元类,类对象的 isa 指针指向元类。

objc_getMetaClass 的核心作用就是获取指定类的元类对象

isa指针概念

每个 OC 对象的第一个成员变量 就是 isa 指针,它指向该对象所属的类,是 OC 消息发送机制的核心。

isa的三条链

第一条: 实例->类对象
objc 复制代码
Dog *dog1 = [[Dog alloc] init];
Dog *dog2 = [[Dog alloc] init];

// 两个实例的 isa 都指向同一个 Dog 类对象
dog1->isa == dog2->isa == [Dog class] // YES

在 Objective-C 中:

  1. 类对象(如Dog类对象)是单例的,程序运行期间只会存在一个。
  2. 每次通过[[Dog alloc] init]创建实例时,新实例的isa成员都会指向这个唯一的Dog类对象,所以dog1->isadog2->isa会指向同一个地址,与[Dog class]的结果也完全相等。

同一个类的所有实例对象的isa指针,都会指向这个类唯一的类对象

第二条 类对象 -> 元类
objc 复制代码
// Dog类对象的 isa 指向 Dog 元类
[Dog class]->isa == objc_getMetaClass("Dog") // YES
```
```
Dog类对象 ──isa──► Dog元类
第三条 元类 -> 根元类 -> 自己
objc 复制代码
// 所有元类的 isa 最终指向 NSObject 元类
// NSObject 元类的 isa 指向自己,形成闭环
Dog元类 ──isa──► NSObject元类 ──isa──► NSObject元类(自己)

isa 完整链路图

复制代码
                    isa                  isa                isa(自己)
Dog实例    ────────────► Dog类对象 ────────► Dog元类 ──────────► NSObject元类
                              │                 │                    │  ▲
               superclass     │   superclass    │    superclass      │  │
                              ▼                 ▼                    ▼  │isa
NSObject实例 ──────────► NSObject类对象 ───► NSObject元类 ───────────┘
                    isa                  isa

这里可以用一张图进行总结

获取元类的方法

objc 复制代码
// 方式一:通过类对象获取元类
Class metaClass = object_getClass([Dog class]);

// 方式二:通过类名字符串获取元类
Class metaClass = objc_getMetaClass("Dog");

// 判断一个 Class 是否是元类
BOOL isMeta = class_isMetaClass(metaClass); // YES

获取元类必须用 object_getClass()objc_getMetaClass(),不能用 [Dog class],因为 [Dog class] 永远返回类对象而不是元类。

相关推荐
小席是个热心肠21 分钟前
AI相关的自我学习
java·人工智能·学习
SuperByteMaster2 小时前
timer.c 介绍
c语言
何事误红尘3 小时前
Mqtt学习笔记(一):Mosquitto服务器搭建、MQTTX安装测试
学习
青山是哪个青山3 小时前
LangChain 学习笔记(三):LangSmith 调试与监控
笔记·学习·langchain
qq_448011164 小时前
C语言中的柔性数组
c语言·开发语言·柔性数组
那年窗外下的雪.5 小时前
AIDC 学习日志 第 04 天 BGP Underlay 基础与路由选择
服务器·学习·php
蒸蒸yyyyzwd5 小时前
cpp选手备战后端学习笔记day6 秋招笔试题
笔记·学习
luj_17687 小时前
塔防牌:策略与卡牌的智慧碰撞
服务器·c语言·开发语言·经验分享·算法
weixin_446260857 小时前
AVA-Encoder:面向智能体原生视频表征学习框架
学习·音视频
wuyk5557 小时前
3.链表:用指针串联的动态数据结构
c语言·开发语言·数据结构·链表