返回

揭秘iOS底层:alloc、new与对象的创建

IOS

深入揭秘 alloc 和 new:iOS 对象创建的幕后机制

前言

在 iOS 开发中,对象创建是一个至关重要的任务。alloc 和 new 是两个常用的方法,但它们在底层是如何运作的呢?本文将深入探究 alloc 和 new 的幕后机制,揭示它们在创建和管理对象时所扮演的角色。

alloc 与 new:异曲同工,各有千秋

alloc 和 new 都是创建对象的途径,但它们之间存在着一些细微差别。

  • alloc 是一个类方法,它返回一个指向新对象的指针。
  • new 是一个实例方法,它返回一个指向新对象的引用。

在大多数情况下,alloc 和 new 是等价的,但 new 隐式地调用了 alloc,因此从本质上来说,这两个方法最终都归结为 alloc。

alloc 的底层奥秘

当调用 alloc 时,以下步骤将依次发生:

  1. 查找类对象: 运行时首先找到与调用 alloc 的类关联的类对象。类对象包含有关类的元数据,包括其大小、方法和属性。
  2. 分配内存: 根据类对象中的大小信息,运行时分配一块内存。这块内存将成为新对象的居所。
  3. 初始化对象: 运行时调用对象的构造函数来初始化其成员变量。构造函数负责将对象置于一个已知的状态。
  4. 返回对象指针: 最后,运行时返回一个指向新对象的指针。这个指针可以用来访问和操作对象。

内存管理:堆上舞者

在 Objective-C 中,对象驻留在堆上。这意味着它们被存储在堆栈帧之外的内存区域中。堆栈用于存储临时数据,而堆则用于存储对象。

alloc 负责分配新对象的内存。当对象不再需要时,必须显式释放其内存。这可以通过调用对象的 dealloc 方法来实现。dealloc 方法负责释放对象占用的内存。

底层实现:运行时库的功劳

alloc 和 new 的底层实现取决于平台。在 iOS 上,alloc 和 new 都由运行时库提供。运行时库是一组管理内存和对象生命周期的 C 函数。

alloc 和 new 的 C 语言签名如下:

void *objc_msgSend(id self, SEL _cmd, ...);

其中:

  • self 是接收消息的对象。对于类方法,这是类对象;对于实例方法,这是对象本身。
  • _cmd 是消息。对于 alloc,这是 @selector(alloc);对于 new,这是 @selector(new)
  • ... 是可变数量的参数。对于 alloc 和 new,没有参数。

当调用 alloc 时,运行时库执行以下步骤:

  1. 根据类对象查找类元数据。
  2. 分配一块与类大小相同的内存。
  3. 将对象指针返回给调用方。

示例代码:亲身体验

以下示例代码展示了如何使用 alloc 和 new 来创建 NSString 类的实例:

// 使用 alloc
NSString *string1 = [NSString alloc];

// 使用 new
NSString *string2 = [[NSString alloc] init];

// 输出结果
NSLog(@"string1: %@", string1);
NSLog(@"string2: %@", string2);

输出:

string1: (null)
string2: (null)

请注意,输出结果为 (null),因为我们没有显式初始化字符串的内容。

何时使用 alloc 和 new:微妙差别

通常情况下,使用 alloc 和 new 并没有明显的区别。然而,在某些场景中,使用 alloc 更具优势:

  • 当需要对一个类进行子类化时。
  • 当需要直接访问底层内存时。
  • 当需要创建多个对象的数组时。

结论:掌握对象创建的精髓

通过深入理解 alloc 和 new 的底层机制,我们可以更好地掌握 iOS 中的对象创建过程。这些知识对于优化代码性能和避免内存泄漏至关重要。随着我们对底层原理的了解不断深入,我们能够更有效地开发出健壮、高效的 iOS 应用程序。

常见问题解答

  1. alloc 和 new 的主要区别是什么?

    • alloc 返回一个指针,而 new 返回一个引用。new 隐式地调用了 alloc。
  2. 对象是如何在堆上管理的?

    • alloc 负责分配内存,dealloc 负责释放内存。
  3. 运行时库在 alloc 和 new 中扮演什么角色?

    • 运行时库提供了一组管理内存和对象生命周期的 C 函数。
  4. 什么时候应该使用 alloc 而不用 new?

    • 当需要对一个类进行子类化,直接访问底层内存或创建多个对象的数组时。
  5. 了解 alloc 和 new 的底层机制有什么好处?

    • 可以优化代码性能,避免内存泄漏,并开发出更健壮、高效的应用程序。