在Objective C中检查内存分配的正确方法

时间:2011-01-02 09:23:16

标签: iphone objective-c memory ios memory-management

我想知道在执行一个在Objective C中分配内存的命令之后会有什么正确的方法(我主要是指iOS应用程序)。 我的困境来自这样一个事实,即检查内存分配操作失败是否成功会增加许多行代码,同时想知道这是否有用。 此外,有时内存分配是显而易见的,例如使用'alloc',但有时它们发生在幕后。即使我们检查每一个分配 - 当我们发现它失败时 - 我们实际上做的并不多。所以也许正确的方法是让它失败并让应用程序崩溃? 看看这段代码:

// Explicit memory allocation
NSArray a1 = [[NSArray alloc] initWithObjects:someObj, nil];
if (!a1) {
  // Should we make this check at all? Is there really what to do?
}

// Implicit memory allocation
NSArray a2 = [NSArray arrayWithObjects:someObj, nil];
if (!a2) {
  // should we make this check at all? Is there really what to do?
}

您认为正确的做法是什么?检查或不检查分配失败?那里的iOS开发者 - 你是如何在你的应用程序中处理它的?

4 个答案:

答案 0 :(得分:11)

幻想:每个内存分配都会被检查,任何失败都会以友好的方式报告给用户,应用程序会干净地关闭,会发送错误报告,你可以修复它并且下一个版本将是完美的(在那个案例中)。

现实:当像arrayWithObjects:这样微不足道的事情失败时,你的应用程序已经很久很久了。在这种情况下没有恢复。框架很可能已经失败了,并且已经破坏了应用程序的状态。

此外,一旦像arrayWithObjects:那样基本的东西失败了,你无论如何都无法告诉用户。没有进一步的分配,你无法在屏幕上可靠地放置对话框。

但是,在您的应用分配失败之前,失败发生得更远。也就是说,您的应用程序应该已收到内存警告,并应响应(a)持久状态,以便不丢失客户数据;(b)尽可能多地释放内存以避免灾难性故障。

尽管如此,内存警告仍然是内存使用战争中最后一道可行的防线。

您对减少记忆的第一次攻击是在设计和开发过程中。您应该从应用程序开发过程开始时考虑内存使用,并且必须优化内存使用,以便在您浏览应用程序以进行发布时。使用分配工具(参见Heapshot analysis write-up我之前做过的 - 它非常适用)并证明每个主要的记忆消费者都存在。

答案 1 :(得分:2)

iPhone应用应注册UIApplicationDidReceiveMemoryWarningNotification通知。当可用内存不足时,iOS会发送这些内容。 Google iphoneappprogrammingguide.pdf(日期为10/12/2011)了解更多信息。

那就是说,我所看到的问题的一个通用方法是在app启动时保留一块内存作为“缓冲”。在你的代码中,在每次分配后进行测试。如果分配失败,请释放缓冲区,以便有足够的内存来显示错误消息并退出。垫子的大小必须足够大,以容纳你的蹒跚学步的应用程序很好地关闭。您可以使用记忆压力测试仪确定垫子的大小。

这真是一个棘手的问题,因为它很少发生(对于精心设计的程序)。在PC / mini /大型机世界中,虚拟内存几乎消除了大多数病态程序中的问题。在有限的内存系统(如智能手机)中,使用堆监视工具对应用程序进行压力测试可以很好地指示其最大内存使用情况。您可以编写一个高水位标记包装程序,用于执行相同操作的alloc。

答案 2 :(得分:0)

检查它们,在调试中断言(因此您知道故障存在于何处/原因),并将错误推送到客户端(在大多数情况下)。客户端通常会有更多上下文 - 他们是否会使用较小的请求重试?以某种方式失败?禁用功能?向用户显示警报等等。您提供的示例不是世界末日,您可以从许多人中优雅地恢复 - 此外,您需要(或应该)知道程序失败的时间和地点。

答案 3 :(得分:-2)

凭借你在智能手机/智能手机中拥有的强大功能,计算一些测试所花费的时间是荒谬的,可以考虑“它真的值得检查”,它始终是一个很好的测试,可以捕获你的代码/分配中的任何失败。 (如果你不这样做听起来更像是懒得在你的代码中添加一些额外的行。

此外,“让应用程序崩溃”给您的应用程序带来了非常糟糕的印象,用户无缘无故地看到应用程序关闭,并认为它是一个质量差的软件。 你应该总是添加你的测试,如果你不能对错误做任何事情,那么至少你应该在应用程序关闭之前显示一条消息(使用户不那么沮丧)。

跟踪内存分配时有几个选项,比如捕获异常。测试返回的指针是否为nil,检查列表的大小等。

你应该想办法让你的应用程序在分配失败的情况下运行:

  • 如果它是您界面的视图,则会显示一条消息,指出无法加载特定视图...

  • 如果它是主视图和唯一视图,请使用消息正常关闭应用程序

...

我不知道你正在使用什么应用程序但是如果你的内存不足,你应该考虑创建一个系统来分配一个释放的内存作为你在你的应用程序中的进展,这样你总是拥有最大可用内存。它可能比保持缓存的所有内容稍慢,但如果你抑制任何力量关闭,你的app质量会提高。