【问题标题】:Objective-C Object AllocationObjective-C 对象分配
【发布时间】:2012-01-03 21:54:43
【问题描述】:

考虑以下两种数组分配。

NSMutableArray* alpha = [[[NSMutableArray alloc] init] autorelease];

NSMutableArray* beta = [NSMutableArray array];

假设没有其他东西保留alpha或beta,我的理解是两者的结果是一样的。两者的保留计数都将为 0,因此一旦它们离开作用域,它们就会被清除。

我有一个偷偷摸摸的怀疑,我没有完全理解这两者之间的微妙含义。阅读StackOverflow 的答案后,我知道后者是一种方便的方法,但我想了解其中的区别。

上面两行代码在内存管理方面有什么区别?

【问题讨论】:

  • 好问题;我想知道ARC之前和之后的这两行是否有区别......
  • 我知道这个问题已经得到解答,但我无法抗拒! The retain count on both will 0 非常具有误导性 - 在自动释放池下一次释放它的对象之前,保留计数将至少 1。而且您根本不能依赖保留计数,因为您不知道框架字中还有什么保留了您的对象,因此它可能不止一个(并且它可能已多次添加到自动释放池中!)。而且你不知道自动释放池何时释放它的对象。

标签: objective-c memory-management


【解决方案1】:

这两行是等价的。在这两种情况下,都会创建您有引用但没有拥有引用的对象。但是,它们将在自动释放池中。这意味着它们将与池一样长,如果您没有做任何特别的事情,直到控制返回到运行循环。因此,像这样的对象(通常)会在其范围之外存活——这很有用,因为这意味着您可以(并且通常会)提供自动释放的对象作为返回结果。

规则是返回对象但名称中不包含“new”、“alloc”、“retain”或“create”的方法将返回一个自动释放的对象。这就是 +array 返回自动释放对象背后的逻辑。

顺便说一句:如果您启用 ARC,则仍会返回自动释放的对象,但编译器可能足够聪明,可以将它们从自动释放池中取出(这是您无法手动执行的操作)并在在不影响程序流程的地方调用方法。

【讨论】:

  • 感谢您验证我的假设并为我清理与自动释放池相关的灰色区域。
【解决方案2】:

不,你是对的。 +[NSMutableArray array] 内部可能看起来很像这样:

+ (id)array
{
    return [[[self alloc] init] autorelease];
}

像+[NSMutableArray array] 这样的“工厂方法”只会为您返回一个自动释放的实例。实际上,在某些优化的 Cocoa 和 Foundation 类中,它的作用远不止于此,但出于内存管理语义的目的,它确实如此简单。

【讨论】:

  • 只是吹毛求疵:[NSArray array] 可能会给你一个空不可变数组的单例实例。你可能是想说[NSMutableArray array]。
  • 感谢您验证我的假设并让我深入了解+ (id)array。
  • @Kevin Ballard,我的意思是说[NSMutable array],但我实际上指的是你在我的“比这更重要”的警告中提到的那种情况。尽管如此,[NSArray array] 返回的单例空不可变数组可以而且应该完全像自动释放对象一样对待。感谢您发现错字。
  • 我想我必须认识到正确输入+[NSMutableArray array] 并不是我的强项;-)。无论如何,我已经更新了我的答案来修复它。
【解决方案3】:

两者确实没有任何区别,除了第二个看起来更干净,字节数更少。

正如您提到的,[NSMutableArray array] 只是一种方便的方法,实际上它在内部实际上会返回第一个方法正在执行的操作。

【讨论】:

  • 感谢您验证我的假设。
【解决方案4】:

完全没有区别。这只是一个捷径。

【讨论】:

  • 感谢您验证我的假设。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-01
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 2011-08-16
相关资源
最近更新 更多