线程如何与其NSAutorelease池相关?

时间:2012-01-02 06:37:46

标签: objective-c ios nsthread nsautoreleasepool

我对NSAutorelease池的工作原理有一个大概的了解。 我们在其中有自动释放的对象以及调用排水方法时。 检查池中零件数量为+1的对象,然后取消分配。

但我不确定的是。 我们在主线程中创建NSAutoRelease池的对象以及每个线程一个。 线程如何与该特定池相关。 如果我们在一个线程中创建两个或更多自动释放池,会发生什么。

我们只需创建池对象并在完成工作后将其耗尽。 它不像我们得到单身或其他东西。

然后线程如何到达该特定池?

解释我的意思是保留计数1. [稍微不正确,请阅读编辑]

  • Obj A有一个方法createAndReturn。
  • createAndReturn创建一个对象autorel_obj并将其返回。

现在它不能只是发布它,因为它必须返回它。 所以它会自动释放并返回。

因此autorel_obj将在自动释放池中。 现在说objB调用ObjA的createAndReturn。

并获取autorel_obj并保留它,否则自动释放池将耗尽它。 现在当它被objB保留时,它的保留计数为2。

[以下是修正的错误部分,编辑]

自动释放池只能释放autorel_obj,直到它也被objB使用。 这就是为什么直到objB也释放它并且它的保留计数变为'1',它才能被释放。

所以通过retainCount 1,我的意思是将它发送到池中的对象是唯一拥有它的对象。

关于池和线程的关系,Firoze Lafeer的答案很有帮助。

编辑以保留计数1方案: 正如Firoze正确指出的那样, 我之前对保留计数1的解释需要改变。

autorel_obj仅在池耗尽时释放,因此其保留计数将减少1。 它不会从记忆中解除分配。 一旦autorel_obj的每个其他所有者obj释放它并且其保留计数变为0。 然后只从内存中释放出来。

很抱歉所有的麻烦,感谢Firoze的纠正。

1 个答案:

答案 0 :(得分:3)

  

检查池中retaincount为+1的对象,然后取消分配。

我不确定我完全理解这句话,但这对我来说听起来不对。自动释放没有任何条件。如果你自动释放一个对象,那么当池被耗尽时被释放,而不管它在那时的保留计数(即使该对象已经被释放!)最好考虑“autorelease”作为“延期释放”。

至于另一个问题,每个线程都维护着自己的自动释放池堆栈。每个池都与一个(也是唯一一个)线程相关联。

哪个线程与给定的池相关联?答案是创建池的任何线程。如果您创建了一个已存在的新池,则新池将“嵌套”在现有池中。当该池被耗尽时(当该池的范围结束时)将释放在该新池范围内自动释放的对象。

我希望有帮助吗?

修改

解决您的修改问题:

您的解释不正确。自动释放池可以并且一旦排出就释放对象。它不会等待objB首先释放它。它甚至不知道其他对象可能从您的示例中保留了autorel_obj。我认为你释放释放令人困惑。

所以场景是这样的:

  • createAndReturn分配和自动释放autorel_obj(保留计数 +1
  • objB保留autorel_obj(保留计数 +2
  • 池已耗尽,autorel_obj由池释放(保留计数 +1
  • 在将来的某个时候,objB发布autorel_obj(保留计数 0
  • autorel_obj已取消分配

因此,同样,池不知道并且不关心其他对象可能保留了它正在释放的对象。当耗尽时,它会释放无条件。这可能不会立即导致对象被释放,但这不是游泳池的关注点。