iPhone - 应用程序被弹出
Posted
技术标签:
【中文标题】iPhone - 应用程序被弹出【英文标题】:iPhone - application being ejected 【发布时间】:2010-02-22 19:45:14 【问题描述】:我有一个应用程序因“内存不足”而被 iPhone OS 弹出。
我已经通过仪器,我看到零泄漏,内存使用量约为 640 kb。
当我向屏幕添加对象时应用程序崩溃。
这就是它的工作原理。我有一个非常简单的基于 UIImageView 的类,并向对象添加了一些属性。此类用于创建的对象。
当用户点击按钮时,会创建该类的新图像并将其添加到 self.view。
添加大约 15 个对象后,应用程序将被弹出并显示内存不足警告。
仪器报告没有显着的内存使用情况。即使添加了 15 个对象,ALL ALLOCATIONS 条目也永远不会超过 660 kb。每个对象可以是五分之一的 120x120 像素图像。
如果不是对象分配或泄漏,那会是什么?请告诉我应该按照哪些方向来定位问题。
感谢您的帮助。
【问题讨论】:
【参考方案1】:ObjectAlloc 工具不会指示应用程序中的所有内存使用情况。视图和其他可视元素在 ObjectAlloc 中不会显示它们的完整大小,因此您需要使用内存监视器工具来查看应用程序在任何给定时间的实际内存大小。
此外,Instruments 不报告泄漏并不意味着它们不存在。通过 Clang 静态分析器运行您的应用程序以再次查看潜在的内存泄漏(通过 Xcode 3.2 下的 Build | Build and Analyze 或 downloading the standalone tool)。同样,即使这通过了,并且您仍然看到内存消耗不断增加,但您在某处存在泄漏。
您提到在您的 cmets 中使用 Quartz 绘图。您需要记住 Quartz 中使用的 Core Foundation 对象也遵循特定的内存管理模型,其中您使用名称中包含 Create
的函数创建的所有内容都必须使用类似 CFRelease()
的匹配函数来释放。如果您忘记了这一点,这可能不会显示为泄漏,但确实如此。
【讨论】:
Clang 报告零问题。 Instruments 报告零泄漏。 Instruments 报告内存分配低于 700 kb。我在 Quartz 中使用的每个变量都有一个 CFRelease。我跟你说。石英是问题。如果你们愿意,我可以在一个类中使用一个非常简单的石英函数来准备一个项目,你可以自己看。当我移除石英功能并且石英方法没有泄漏和错误时,问题消失了。我看到问题是泄漏(只有 Apple 可以修复)和未释放缓存内存的混合。 当您说“仪器报告内存分配低于 700 kb”时,是在 ObjectAlloc 还是内存监视器仪器中?正如我所说,ObjectAlloc 不会显示应用程序的真实大小,而 Memory Monitor 会显示。如果我没记错的话,即使是非常简单的应用程序也会使用 1.5 - 2 MB 的总内存。 我已经包含了一个项目,您可以在其中看到问题。【参考方案2】:泄漏不是您的问题。过度保留是。
查看对象分配。如果该图只是上升和上升,您的应用程序将被终止。让 iPhone 特别生气的是当你被告知释放一些内存(内存不足警告)并且没有释放内存时。您的代码可能只是这种情况的一个极端情况,但是当您收到此消息时应该释放一些东西。
【讨论】:
正如我在问题中所说,我的应用程序没有泄漏,我的内存使用量低于 700 kb,但应用程序崩溃了。罪魁祸首是石英。这次我能够用非石英方法替换该方法,并且该应用程序现在像丝绸一样光滑。我所有使用石英的应用程序都有同样的问题。啊,当我收到内存警告时,我没有什么可释放的。我的应用占用空间小。 我已经包含了一个项目,您可以在其中看到问题。【参考方案3】:我发现问题与我的代码无关。每次我在 iPhone 上使用石英时都会遇到这种问题。
Quartz 有一个严重的问题需要解决。据我检测,它会获取大量内存来执行绘图并且即使您释放所有使用的变量和引用也不会释放它们。即使你把所有变量都设为 nil。
Quartz 是内存消耗者,也是崩溃的根源。
这是我创建的一个项目,用于演示 Quartz 如何使您的项目崩溃。在 MyClass.m 内部寻找一个名为 imageWithBorderFromImage 的方法。此方法使用石英在对象周围绘制虚线边框。运行项目并在按钮中单击几次。每次单击时,屏幕上都会在前一个对象之上添加一个新对象。大约 20 次点击后,应用程序被跳板弹出。在此之前,您会在控制台上看到内存不足警告。
在告诉我问题是创建了太多视图之前,请禁用石英方法并查看应用程序不再崩溃。事实上,我可以点击 80 次,仍然可以继续点击,但我停止了应用。
Download the project QuartzNightmare here
【讨论】:
你能确定任何特定的电话吗?在什么操作系统版本上?我的应用程序中没有任何 Quartz 内存问题。 我非常怀疑这是 Quartz 绘图系统的问题,因为 Quartz 几乎用于绘制操作系统中的每个视觉元素。我在我的应用程序中使用了大量的 Quartz 绘图,并且从来没有它成为不是我的错的内存泄漏的来源。正如我在回答中解释的那样,您可能因为未正确释放为绘图目的而创建的 Core Foundation 对象而导致内存泄漏。这可能没有显示为 Instruments 中的泄漏。 我已经包含了一个项目,您可以在其中看到问题。 查看您的项目,问题似乎是您一直在向屏幕添加视图,而从未删除任何视图。如果您在添加新视图之前删除了旧视图,我敢打赌您不会遇到这个问题。这不是 Quartz 问题,也不是内存泄漏,但是您创建的所有这些视图仍然消耗大量内存。 好的,但请再次尝试删除项目的石英部分并告诉我应用程序是否崩溃...我的另一个应用程序添加了一个视图并使用在该图像上绘制边框和其他内容的类似方法,它会在一段时间后崩溃。在该项目中,图像具有 500x500 像素,quartz 生成的内存使用量为 36 MB 内存。为什么石英使用 38 Mb 内存确实在使用 1 MB 内存的图像上画一条线是一个谜。显然,它崩溃了。以上是关于iPhone - 应用程序被弹出的主要内容,如果未能解决你的问题,请参考以下文章
当我的 UIViewController 被弹出时调用的方法?
viewWillDisappear:判断视图控制器是被弹出还是显示子视图控制器