【问题标题】:How are objects in an autorelease pool referenced?如何引用自动释放池中的对象?
【发布时间】:2010-10-22 07:01:33
【问题描述】:

我想知道自动释放池是否持有对其持有的对象的强引用或弱引用。我猜他们很弱。当我将对象添加到自动释放池时,它不会立即释放,而是会在池耗尽时释放,对吗?所以引用应该是弱的,即当我将对象添加到自动释放池时,引用计数(或保留计数)保持不变?

【问题讨论】:

    标签: iphone cocoa-touch memory-management autorelease


    【解决方案1】:

    保留计数保持不变,基本上在对象上触发自动释放消息使开发人员无需承担所有权和释放责任。

    这就是自动释放池的工作原理—— 每次创建自动释放池的实例时,它都会添加到堆栈顶部,因此系统将使用最新的自动释放池。并且每当您在自动释放池中添加任何对象时,它都会添加到堆栈中的顶部自动释放池中。自动释放池基本上是一个数组,其中添加了自动释放的对象。当特定的自动释放池被释放(/耗尽)时,自动释放池中添加的每个对象都会被释放。在系统开始处理任何事件之前首先创建一个自动释放池,并且它一直存在直到当前事件循环的执行结束。当系统看到当前事件循环完成时,它会获取与该事件循环关联的最顶层自动释放池并释放它。释放自动释放池/排空意味着将每个对象添加到自动释放池中并在对象上触发释放消息,直到自动释放池中的所有对象都被释放。

    【讨论】:

      【解决方案2】:

      在垃圾回收内存管理环境(弱指针即使被引用也会自动释放和清除)的上下文中,谈论强引用和弱引用是有意义的。启用 GC 后,所有的 retain/release/autorelease 调用基本上都是什么都不做的操作(尽管 NSAutoreleasePool -drain 方法会触发垃圾回收)。

      现在,既然您已将此问题标记为与 iPhone 相关,并且 iPhone 上没有垃圾收集,我假设您指的是常规引用计数,强表示您的意思是增加引用对象的保留计数,并且弱的意思是只存储指针值。

      autorelease 方法本质上是将对象的所有权从调用代码转移到当前的自动释放池中,您可以认为调用代码调用释放和池调用保留。

      所以引用实际上是强大的,但您的代码失去了所有权和发布责任。对象release 将在自动释放池被释放/耗尽时被调用。

      【讨论】:

        【解决方案3】:

        自动释放池的全部意义在于它是一个延迟释放。例如,您可以对将在方法中返回的本地对象调用 autorelease,这样即使在方法返回时您丢失了对该对象的引用,它也会被释放。

        【讨论】:

          【解决方案4】:

          是的。保留计数保持不变,您可以检查一下:

          id obj = [[NSObject alloc]init];
              NSLog([NSString stringWithFormat: @"%d", [obj retainCount]]);
              [obj autorelease];
              NSLog([NSString stringWithFormat: @"%d", [obj retainCount]]);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-09-10
            • 1970-01-01
            • 2011-07-01
            • 2011-08-19
            • 1970-01-01
            • 2013-04-16
            相关资源
            最近更新 更多