返回

深入探究isa和类结构:揭秘Objective-C语言幕后运行机制

IOS

一、isa到元类

1. isa指针

isa指针是Objective-C语言中的一个关键概念,它指向对象的类对象。类对象是类信息的特殊对象,它包含了该类的方法列表、成员变量列表以及其他元数据。

2. isa指针的获取

对象的isa指针可以通过多种方式获取:

  • 使用classclass关键字返回对象的类对象。
  • 使用isa指针。isa指针直接指向对象的类对象。
  • 使用objc_getClass()函数。objc_getClass()函数接收一个类名作为参数,并返回该类的类对象。

3. isa指针的作用

isa指针的作用主要包括以下几个方面:

  • 确定对象的类。通过isa指针,可以确定对象的类,从而调用该类的方法和访问该类的成员变量。
  • 查找类的方法。当调用对象的方法时,编译器会根据isa指针找到该方法的实现。
  • 确定对象的类型。isa指针可以用来确定对象的类型,从而进行类型检查。

二、isa走位图和继承链

1. isa走位图

isa走位图是isa指针中的一个重要组成部分。isa走位图包含了该对象继承链上的所有类。

2. isa走位图的结构

isa走位图的结构如下:

|--------------------|--------------------|
|      Class       |      Class       |
|--------------------|--------------------|
|      Class       |      Class       |
|--------------------|--------------------|
|......            |......            |
|--------------------|--------------------|

3. isa走位图的作用

isa走位图的作用主要包括以下几个方面:

  • 快速查找继承链上的类。通过isa走位图,可以快速找到继承链上的所有类。
  • 确定对象的类型。isa走位图可以用来确定对象的类型,从而进行类型检查。

三、源码分析类的结构

1. 类结构

Objective-C中的类结构如下:

struct objc_class {
    Class isa;  // 指向该类的元类
    Class superclass;  // 指向该类的父类
    const char *name;  // 该类的名字
    long version;  // 该类的版本号
    long info;  // 该类的信息
    long instance_size;  // 该类的实例大小
    long ivar_layout;  // 该类的成员变量布局
    long method_count;  // 该类的方法数量
    struct objc_method_list **methodLists;  // 该类的所有方法列表
    struct objc_cache *cache;  // 该类的缓存
    struct objc_protocol_list *protocols;  // 该类实现的所有协议
};

2. 类结构的组成部分

  • isa指针:指向该类的元类。
  • superclass指针:指向该类的父类。
  • name:该类的名字。
  • version:该类的版本号。
  • info:该类的信息。
  • instance_size:该类的实例大小。
  • ivar_layout:该类的成员变量布局。
  • method_count:该类的方法数量。
  • methodLists:该类的所有方法列表。
  • cache:该类的缓存。
  • protocols:该类实现的所有协议。

四、指针和内存平移

1. 指针平移

指针平移是指将一个指针从一个内存地址移动到另一个内存地址。指针平移可以通过以下方式实现:

  • 使用指针算术。指针算术可以通过+-运算符来实现。
  • 使用memmove()函数。memmove()函数可以将一个内存块从一个地址移动到另一个地址。

2. 内存平移的作用

内存平移的作用主要包括以下几个方面:

  • 将对象从一个内存地址移动到另一个内存地址。
  • 将数据从一个内存地址移动到另一个内存地址。

五、类的结构内存计算

1. 类的结构内存计算公式

类的结构内存计算公式如下:

sizeof(struct objc_class) = sizeof(Class) + sizeof(Class) + sizeof(const char *) + sizeof(long) + sizeof(long) + sizeof(long) + sizeof(long) + sizeof(struct objc_method_list **) + sizeof(struct objc_cache *) + sizeof(struct objc_protocol_list *)

2. 类的结构内存计算示例

假设一个类的结构如下:

struct objc_class {
    Class isa;  // 8字节
    Class superclass;  // 8字节
    const char *name;  // 8字节
    long version;  // 8字节
    long info;  // 8字节
    long instance_size;  // 8字节
    long ivar_layout;  // 8字节
    long method_count;  // 8字节
    struct objc_method_list **methodLists;  // 8字节
    struct objc_cache *cache;  // 8字节
    struct objc_protocol_list *protocols;  // 8字节
};

那么,该类的结构内存大小为:

sizeof(struct objc_class) = 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 = 88字节

六、lldb分析类的结构和类的bits数据分析

1. lldb分析类的结构

可以使用lldb来分析类的结构。以下命令可以分析类的结构:

po [class_name class]

2. lldb分析类的bits数据

可以使用lldb来分析类的bits数据。以下命令可以分析类的bits数据:

po [class_name class]->bits

3. lldb分析类的结构和类的bits数据示例

以下是在Objective-C中定义的一个类:

@interface MyClass : NSObject

@end

@implementation MyClass

- (void)sayHello {
    NSLog(@"Hello, world!");
}

@end

可以使用lldb来分析该类的结构:

(lldb) po [MyClass class]
<objc_class: MyClass>

可以使用lldb来分析该类的bits数据:

(lldb) po [MyClass class]->bits
{isa = 0x0000000104d70b80, superclass = 0x0000000104d87db0, name = MyClass, version = 45, info = 0, instance_size = 32, ivar_layout = 0, method_count = 1, methodLists = 0x000000010c1e9310, cache = 0x00000000, protocols = 0x00000000}

从以上分析结果可以看出,MyClass类的结构和bits数据与前面介绍的内容是一致的。