目标 C:保留/释放内联分配的对象

Posted

技术标签:

【中文标题】目标 C:保留/释放内联分配的对象【英文标题】:Objective C: Retain/Release for objects allocated inline 【发布时间】:2011-12-31 21:57:39 【问题描述】:

根据我对通过保留/释放管理内存的“规则”的理解,如果您分配/复制/保留一个对象,您必须始终(最终)释放它:

id foo = [[MyClass alloc] init];
id bar = [[MyClass alloc] init];
[bar takeOwnership:foo]; //bar retains foo
[foo release]; //I'm done with it now, so I release it

如果我想改为创建 foo inline 该怎么办,如下所示:

id bar = [[MyClass alloc] init];
[bar takeOwnership:[[MyClass alloc] init]];

当我分配它时,我显然不能释放以前称为 foo 的对象,如果没有引用,我以后也不能释放它。实际上,采用“如果你拥有它,你必须释放它”的方法似乎意味着如果你不希望它最终泄漏,你就不能内联分配对象。

那么:内联分配东西真的被禁止吗?虽然上面的例子有点做作并且明显的解决方案就是不这样做,但在我看来,在某些情况下,能够这样做在语义上是可取的(事实上,我发现自己在这样的情况下)一种情况)。在这些情况下 - 也就是说,假设我希望能够如上所示内联分配对象 - 有没有办法做到这一点而不会完全破坏对象不是内联分配的“正常”情况?

如果有帮助,我可以提供有关我正在尝试做的事情的详细信息,但希望以上内容能解决我的问题。

【问题讨论】:

一个简单的答案是不要那样做——做单独的分配。或者使用自动释放。我相信在 Objective-C 中你可以做类似 id temp; [bar takeOwnership:temp = [[MyClass alloc] init]]; [temp release]; 的事情,如果这能让你感觉更好的话,但是在功能或性能方面,单行语句与多语句相比并没有真正的优势。 但是,如果你觉得你必须做一个单行,出于某种模糊的原因,并且takeOwnership 是你自己的方法,让它返回它的参数和代码[[bar takeOwnership:[[MyClass alloc] init]] release];。跨度> 【参考方案1】:
[bar takeOwnership:[[MyClass alloc] init]];

如果您使用的是 ARC(您应该使用),那么您不会做任何不同的事情。它“正常工作”。

如果您使用手动保留释放 (MRR),则:

[bar takeOwnership:[[[MyClass alloc] init] autorelease]];

请注意,自动释放压力可能是性能问题;即,出于这个原因,您可能希望避免使用带有自动释放的内联案例。但是,除非您在池被耗尽之前通过此代码路径 100s/1000s 次,否则不要担心。

【讨论】:

如果我既不使用 ARC 也不使用自动释放池怎么办?具体来说:我在嵌入式环境(不是 iPhone/iPad)中使用 Objective C,在这种环境中自动释放池之类的开销使它们有些昂贵,而 ARC 根本不可能。在这种情况下,我是否只需要完全避免这种方法? 为什么不能使用 ARC?这是一个编译时特性;它不会强加任何运行时开销。 好点 - 我把它与 ObjC2 垃圾收集混淆了。我会看看如何启动并运行 ARC - 谢谢!

以上是关于目标 C:保留/释放内联分配的对象的主要内容,如果未能解决你的问题,请参考以下文章

目标 C:线程之间的自动释放对象?

目标 C:释放和分配

我应该在重新分配之前调用分配给保留属性的自动释放对象的释放吗?

将自动释放的对象分配给保留的属性

代表 - 保留或分配 - 释放?

自动释放对象递减的保留计数何时减少?