【问题标题】:Why should I release (and therefore dealloc) objects just before application quit?为什么我应该在应用程序退出之前释放(并因此释放)对象?
【发布时间】:2010-12-04 17:54:43
【问题描述】:

每个 iPhone 应用程序中都有很多对象将永远存在,直到应用程序消亡。它们是:应用程序委托、窗口、主视图控制器,可能是导航或选项卡控制器,它们中的所有对象。为什么我应该在停止花费宝贵的 CPU 周期之前释放它们?据我了解,应用程序进程将被终止,因此它的堆,一致与否也将消失。

那么我为什么要释放它们呢? Apple 的开发手册坚持它就像在代码示例中一样(来自iPhone Development Guide)。这只是我在图书馆中找到的第一个按词 dealloc 搜索的地方。

@implementation HelloWorldAppDelegate
@synthesize window;

- (void)applicationDidFinishLaunching:(UIApplication *)application { 

    // Override point for customization after app launch
    MyView *view = [[MyView alloc] initWithFrame:[window frame]];
    [window addSubview:view];
    [view release];
    [window makeKeyAndVisible];
}
- (void)dealloc {
    [window release];
    [super dealloc];
}
@end

来自NHObject-dealloc 方法的讨论部分:

请注意,当应用程序终止时,可能不会向对象发送 dealloc 消息,因为进程的内存在退出时会自动清除 - 简单地允许操作系统清理资源比调用所有内存管理方法。由于这个和其他原因,您不应该在 dealloc 中管理稀缺资源

但如果您的应用程序足够快以在 15 秒内对 applicationWillTerminate 做出反应,则在当前实现中调用上面示例中的 dealloc 方法。

再说一遍。我应该避免为应用退出速度编写上面的 dealloc 方法还是这种方法有任何问题?

【问题讨论】:

  • 苹果的说明书在哪里坚持呢?我曾一次或多次阅读过他们的大部分文档,但不记得了——事实上,我记得在几个地方读过相反的内容,即不解除分配对效率更好。
  • Apple 还声明,不能保证在其中某些类退出时您会得到一个 dealloc 调用。因此,将代码保存在您的 dealloc 例程中将是一件坏事。
  • 在这种情况下,何必为他们写dealloc代码呢?
  • @Chuck 我没有找到你提到的任何优化技巧。非常感谢您发布其中一个作为此问题的答案。
  • 应用的原则是所有类都应该有一个-dealloc,以防你重用它们。 (例如,您可能想要编写单元测试。)确保在您退出时释放每个对象并不是一个好主意,Apple 也不鼓励这样做。这是浪费时间和精力。 (事实上​​,在 Mac OS X 10.6 中,有一个 API 可以让系统在不保存任何内容的情况下立即终止您的应用,以节省时间和电力。我希望这将在 iPhone 4.0 中实现。)

标签: iphone objective-c cocoa cocoa-touch


【解决方案1】:

因为释放的类可能会产生副作用,例如在其 dealloc 方法或其中一个超类中保存状态。操作系统不应该关心,无论如何它都应该回收所有资源。

【讨论】:

  • 在 dealloc 中保存状态?为什么?
  • 在dealloc中保存状态是一个非常糟糕的主意,因为dealloc不能保证执行。 applicationWillTerminate 用于保存状态。
  • 如果你有一个类可以做到这一点,是的,你需要在终止之前释放它。但是 Apple 的文档说要尽可能避免这种情况,因为对象通常不会在终止时被释放。
  • dealloc 可能会做其他工作,但绝不应该这样做。正如其他人所说,不能保证会调用 dealloc。
【解决方案2】:

最好的理由是重用。您有可能将对象从一个地方移动到另一个地方或重新利用它。如果你这样做,最好确保你所有的 i 都被点缀并且 t 被交叉。

这也是一个好习惯。如果你记得在那里做,你会在任何地方做。

【讨论】:

  • 是的,对我来说,这就像开车经过停车场时使用转向灯一样。没必要,但让自己养成这个习惯是件好事。
  • 你不是自动化的——你是人类。机械地一遍又一遍地重复相同的动作而不考虑它可能会损害你的大脑。
  • 重用能力?你是在给我装逼吗?你将如何重用应用程序委托?作为牙棒?
  • 不,我不会重用应用程序委托,但我要做的是意识到我放在那里的一半功能属于其他地方。所以我会制作一个应用程序委托的副本,开始重命名并减少dealloc。然后将所有东西放在正确的位置会有所帮助。
  • stiiv 所说的一个很好的例子是单例。当然,您现在只想要一个实例,但将来您总是可以改变主意。你宁愿现在花 30 秒写dealloc,还是可能在未来数小时追踪内存泄漏?对我来说似乎是很好的保险。
【解决方案3】:

您发布的代码示例并不坚持在应用终止时发布任何内容。如果您正在考虑 dealloc 方法,则在应用程序终止时不会调用它。

在文档的几个地方,Apple 指出在退出时不发送 dealloc 是一种有意的设计选择,因为正如您所说,释放整个地址空间会更有效。请参阅discussion on the dealloc docs

【讨论】:

  • 但是它被调用了。我已经在实际设备上检查过了。而这个特殊的 dealloc 也会强制所有这些对象去 dealloc。他们说:...当应用程序终止时,可能不会向对象发送 dealloc 消息...这意味着如果 15 秒后您的应用程序仍在保存某些内容,它将被终止,无论如何都会跳过释放。
  • 只有在您释放代码所在的对象时才会调用它。运行时不会为您释放它。
【解决方案4】:

我想唯一对我有意义的答案是“一致性”。不,你可能并不总是需要实现dealloc,但如果你总是这样做,你就不会忘记在重要的时候去做。此外,编写两行可能不会被调用的代码不会花费您超过 30 秒的时间。

您也不太可能浪费宝贵的 CPU 周期(顺便说一下,这些周期并不是那么宝贵,以至于您会注意到差异。这些 iPhone 动画的存在主要是为了让您的应用程序有时间启动/关闭down) 因为当应用程序终止时,它通常不会打扰dealloc 对象,因为正如您所说,该堆的内存分配天数已经过去了。

所以,是的,dealloc 不太可能在 UIApplicationDelegate 上被调用,但是这样做是否需要您付出任何代价?不是真的。

【讨论】:

  • 恕我直言,应用程序退出经验很有价值。当然我应该衡量一下,但我认为解除分配可能会非常昂贵。
  • 好吧,既然你已经打定主意了,为什么还要问?
  • 我已经询问过这种方法的问题。很难接受,像苹果这样庞大的团队可以教做不必要的事情。如果激怒了你,我很抱歉。
【解决方案5】:

因为你会知道的,阿尔乔姆。

让我们玩一个小游戏,叫做“如果”。

假设,您开发了一款出色的应用。一个精湛的应用程序,真的 - 公众喜欢它!您的销售量大增,鸟儿在天空中高唱您的名字!

但是,您选择在 AppDelegate dealloc 中不做任何事情。短短几秒的时间,你决定不理会。有什么害处?

哦,一开始你在一堆钱上睡得安稳。但随着销售额的增长和增长,你会感到有点刺痛。然后梦想开始了。

方形,起初不明显。日子一天天过去,它们变得越来越清晰,因为你睡得越来越少。最后,有一天,你看。

它们是方块,Artem。 内存块。他们在你的梦里做什么?好吧,你看,在应用程序退出之前还没有完全摆脱存在,他们不得不去某个地方。应用消失了,手机继续运行。

所以他们搬进了你的HEAD。而且每天都有更多的人到达,留给你自己的空间越来越少。

我希望这可以提供信息... Artem。

【讨论】:

  • 可能是有史以来最好的答案。
猜你喜欢
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多