0

我阅读了 Objective-C 语言的内存管理指南,但我仍然有这个疑问,即使在阅读了很多次之后。

假设我想返回一个我刚刚在这样的对象的方法中创建的对象:

NSString* ret = [[NSString alloc] initWithString:@"My string"];
return ret;

我可以这样做,但根据所有权政策是不正确的。该指南指出,正确的解决方案是:

NSString* ret = [[NSString alloc] initWithString:@"My string"];
return [ret autorelease];

因为,当我自动发布时,我不再是所有者。我的问题是:NSString 什么时候会真正被释放和释放?最后一个初始化的池什么时候释放?这意味着,如果我不创建池,这个对象将在应用程序关闭时释放(xcode 默认创建的池在最后释放)。这个对吗?这同样适用于我未分配的对象,例如:

NSString* ret = [NSString stringWithString:@"My string"];

? 如果我不创建池释放到别处,是在应用程序结束时释放xcode创建的池时释放?感谢您的任何澄清。

4

3 回答 3

2

当您调用 时autorelease,您将所有权交给最近的自动释放池,以便在下一次排水时释放。

必须始终有一个最外层的自动释放池,但通常会有更接近动作的其他池。您不必显式地创建它们——尽管您也可以这样做——它们是由 Cocoa 框架在处理程序业务的过程中创建的。

如果您正在编写一个从不移交给框架的非 GUI 工具,并且您从不创建另一个池,并且从不调用drain现有的池,那么当池本身存在时,对象将在退出之前被释放。否则,它通常会在事件处理周期结束时被释放,这是框架维护池的关键位置之一。

通常,通过便利类方法创建的对象的情况与分配和自动释放的对象相同。碰巧的是,您引用NSString的那个会有点不同,因为它的基础是一个常量字符串,并且不会以完全相同的方式进行管理。但这是一个实现细节。

于 2010-11-27T01:02:13.570 回答
2

对象在自动释放时会进入当前的自动释放池。当池本身被发送release(或drain,这是同一件事)时,其中的对象也被发送release。至于当前的自动释放池在大多数情况下何时创建和释放,关于自动释放的内存管理指南章节说:

Application Kit 在事件循环(或事件循环迭代)开始时自动创建一个池,例如鼠标按下事件,并在结束时释放它

所以在实践中,自动释放的对象会很快消失——在应用程序生命周期结束之前,实际上是在发送下一个 touch/mouseMoved 事件消息之前。

如果需要,可以创建自己的本地自动释放池以使它们更快地消失,但这通常是一个微优化,实际上可能会使事情变得更慢(它增加了发送的消息数量,但不一定会其他任何事情都需要更少的时间)。

于 2010-11-27T02:36:41.780 回答
1

请记住,这-autorelease不过是一个延迟的消息传递工具。当你发送-autorelease到一个对象时,当前的自动释放池会将该对象添加到它的列表中,当池被耗尽或释放时,它会向其列表中的每个对象发送一个-release消息。

于 2010-11-27T01:48:19.070 回答