返回

让 iOS 对象变得触手可及:深入解析内存中的布局

IOS

我们常常会使用 Objective-C 中的 NSObject 类作为应用程序的基础构建元素,它提供了诸如继承、封装等强大的功能。当我们通过 Xcode 中的 Build 命令将一个 .m 文件转化为 C++ 文件时,便揭开了的对象的神秘面纱,使其以更底层的二进制语言的形式呈现。由此,我们可以深入剖析的对象在内存中的布局情况。

其中,需要注意的是,isa 指针在 64 位系统中占用 8 字节空间,而在 32 位系统中则占用 4 字节。

内存中的布局:直观理解对象的构成

当我们在 Xcode 中使用 Build 命令将一个名为 main.m 的文件转化为 C++ 文件后,便可直接看到 对象的内存布局。

// main.cpp
#include <iostream>

using namespace std;

class NSObject {
public:
    // isa 指针,指向其对应的 Class
    id isa;
};

class Person : public NSObject {
public:
    string name;
    int age;
};

int main() {
    // 实例化 Person 对象
    Person person;
    
    // 获取 person 对象的 isa 指针
    id isa = person.isa;
    
    // 输出 isa 指针的值
    cout << "isa 指针的值:" << isa << endl;
    
    return 0;
}

若我们对生成的 output 文件夹进行相应的路径查找,便能够看到对应的 output/main.cpp.obj 文件。其中,我们看到关于 isa 指针的声明 id isa; 位于 main.cpp 文件第一行的开头处。

isa 指针是 NSObject 中的一个重要组成部分,它指向了该 NSObject 实例所属的 Class。在 64 位系统中,isa 指针占用了 8 字节的空间,而在 32 位系统中,它占用了 4 字节的空间。

除此之外,我们还可以看到 Person 继承自 NSObject 时,在 Person 中会包含 NSObject 的全部字段。这意味着 Person 对象除了能够储存 nameage 变量之外,还隐式包含了 NSObject 中的 isa 指针。

深入探究继承与封装:从内存入手

对于继承这一概念,我们应当着重注意以下三点:

  • 类继承: 由基类到派生类的自然演进方式。
  • 子类继承: 派生类吸收并利用基类的所有字段(成员变量和成员函数),并进一步扩充自己的字段,实现新功能。
  • 多继承: 一个子类可以继承多个父类,可同时调用多个父类的函数并访问多个父类的成员变量。

对于封装这一概念,我们应当着重注意以下三点:

  • 访问控制: 保护数据,避免未经授权访问。
  • 信息隐藏: 隐藏不必要的或敏感的实现细节,以实现系统的安全性。
  • 模块性: 鼓励各模块的松散耦合。

总而言之,isa 指针提供了一个指向 Class 实例的指针,它包含指向子类方法和字段的指针。继承是将一个类作为一个基类,并创建一个子类,该子类利用了基类的字段和函数。继承允许子类访问基类的所有成员,而封装是指在子类中包含指向基类的指针。它允许子类访问基类的成员,但子类中的字段可能隐藏或扩展基类中的字段。

结 语:更深刻的理解与应用

通过这篇文章,我们对作为构建元素的 NSObject 在内存中的布局有了更深刻的认识,并对继承和封装这些更广阔的领域也加深了理解。这些概念是十分重要的,希望您能将其运用到实践当中,构建出更为强大的应用程序。

致谢:

感谢您阅读这篇文章,如果您有任何问题或想分享任何想法,请随时留言或与我们互动。我们将尽最大可能确保您获得最佳的经验。

扩展阅读: