Objective-C:为什么自动释放池存在并按照它们的方式工作?

Ask*_*aga 2 memory-management objective-c

我研究了一个关于Objective-C内存管理的教程,我想我明白它是如何工作的.但是,我想知道为什么自动释放池的创建方式与它们的工作方式相同.据我所知,自动释放消息主要用于从函数返回对象时,因为被调用者无法确定调用者是否会将结果实际存储在变量中(稍后需要释放返回的对象).我有一个理论认为,这个概念是在Objective-C仅仅是预处理器的那一天制作的.编译器会知道未分配的返回值,并且可以静默地自动插入返回对象的版本(这种行为意味着必须手动释放每个分配的返回值)

所以我的问题:

  • 我对我的理论是对的,还是有自动释放池概念的其他原因
  • 是否有其他概念来处理基于保留/释放的手动内存管理的返回值问题(不一定是Objective-C特定的)

小智 7

你的解释是部分正确的.是的,自动释放池主要用于从函数或方法返回非拥有对象:您无法在方法中释放对象,或者调用者无法使用它.您可以要求调用者接受从函数或方法返回的对象的所有权,因为Core Foundation使用其Create规则,但Foundation引入了自动释放池并避免了此要求.

然而,这是相关的Objective-C是编译器的预处理器或一部分.它完全依赖于框架和语言使用的内存管理策略.

  • 早期(预处理​​)Objective-C有一个"程序员最了解"的策略,类似于C malloc/ freesystem.它没有自动释放池; 程序员在知道完成后释放了一个对象.
  • 基金会介绍[*]引用计数内存管理,并使用自动释放池实现延迟发布.这是"对象的程序员最了解"策略,其中每个对象可以说出它拥有的内容,但是不需要整体内存管理编码.
  • 垃圾收集的Objective-C存在于至少两个(可能是三个)化身中.即使在Garbage-collecting Foundation中也有自动释放池,但是有一个"运行时知道最佳"策略,因此您可以在没有自动释放池的情况下离开,因为运行时可以看到对象何时仍在使用中.
  • 顾名思义,自动引用计数可自动完成Foundation的引用计数内存管理方案.从理论上讲,您不需要自动释放池,因为编译器和运行时可以告诉对象如何使用并修复所有权.实际上,您仍然可以这样做,因为您可以与手动引用计数代码进行互操作.ARC仍然是"对象的程序员最了解的",但它会降低手动保留和释放,转而支持手动强/弱/不安全的引用标记.

您建议只有当对象别名为编译器可见的命名变量时才应保留该对象在一般情况下不起作用.程序员可以保留对该对象的未命名引用(例如,在集合中或通过关联),或者他们可以创建一个必须保持不变的对象,尽管它没有别名.

[*]事实上,引用计数系统中存在的马赫试剂盒如NXReference(以及在其他框架中使用,像索引试剂盒)更早,但是当它成为基础的一部分成为常规所有Objective-C类(在NeXTStep和WO应用程序,因此在Mac和iOS应用程序中)使用引用计数的内存管理.

  • 引用计数管理作为OpenStep API的一部分[~1993]; 格雷厄姆表示,它在内部使用过.选择它是为了在自动化和效率之间取得平衡.请注意,它也有一些重要的成本.与垃圾收集相比,引用计数是免费的这一概念根本不是真的(实际上,GC可以提供比参考计数*显着的性能改进*,但代价是确定性*). (4认同)