5

这是昨天提出的一个更广泛的问题。我一直在使用 heapshots 来查明问题,但它们都存在于我不熟悉的调用者中。我自己编写的方法没有出现,但 CoreGraphics 似乎在疯狂地吃内存。

本周我已经准备好提交我的应用程序,但遇到了一个大问题。我一直在做很多 QA 和泄漏检测,并且正在通过 heapshot/allocation profiling 完成这个过程。不幸的是,这并没有按计划进行。该程序本身并没有“泄漏”,但毫无疑问它正在攀升。

解释程序的最佳方式是数学抽认卡(第一个应用程序,学习绳索,我想让它变得简单)。有 5 个按钮、2 个图像视图和 2 个 UILabel。我把头撞到墙上,想知道我的设计是否有问题(简短的回答:可能),但更担心内存蠕变几乎肯定不会让我进入应用商店。

因此,过程:视图显示一个主页按钮(用于返回主菜单)、一个复选框(用于标记稍后的问题)、一个 UILabel 中的数学问题和一个获取答案按钮。当您按下获取答案时,答案会显示在第二个 UILabel 中,并且会出现另外两个按钮(正确和错误),并且获取答案按钮标题会更改为“获取问题”。按下 Get Problem 让我们回到开始,遇到一个新问题。

我一直在使用 heapshot 来查找占用了多少内存,并且我发现每次通过一次迭代我都会丢失 10-15KB (按“获取答案”然后按“右”或“错误的”)。最严重的违规者是所谓的“CGGlyphBitmapCreate”,老实说,我对它的实际含义知之甚少。

其他一些注意事项:“主页”按钮是在 IB 中创建的带有 .png 的自定义按钮。根据复选框的状态(我隐藏一个,然后显示另一个,反之亦然),我在两个 .png 之间切换(通过.hidden)的没有文本的“标记”按钮没有文本。

调用堆栈:

0 libSystem.B.dylib calloc
1 CoreGraphics CGGlyphBitmapCreate
2 CoreGraphics CGFontCreateGlyphBitmap8
3 CoreGraphics CGFontCreateGlyphBitmap
4 CoreGraphics CGGlyphLockLockGlyphBitmaps
5 libRIP.A.dylib ripc_DrawGlyphs
6 CoreGraphics draw_glyphs
7 CoreGraphics CGContextShowGlyphsWithAdvances
8 WebCore WebCore::showGlyphsWithAdvances(WebCore::FloatPoint const&, WebCore::SimpleFontData const*, CGContext*, unsigned short const*, CGSize const*, unsigned long)
9 WebCore WebCore::Font::drawGlyphs(WebCore::GraphicsContext*, WebCore::SimpleFontData const*, WebCore::GlyphBuffer const&, int, int, WebCore::FloatPoint const&, bool) const
10 WebCore WebCore::Font::drawSimpleText(WebCore::GraphicsContext*, WebCore::TextRun const&, WebCore::FloatPoint const&, int, int) const
11 WebCore WebCore::Font::drawText(WebCore::GraphicsContext*, WebCore::TextRun const&, WebCore::FloatPoint const&, int, int) const
12 WebKit drawAtPoint(unsigned short const*, int, WebCore::FloatPoint const&, WebCore::Font const&, WebCore::GraphicsContext*, bool, WebCore::BidiStatus*, int)
13 WebKit -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:renderedStringOut:drawUnderline:]
14 WebKit -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:renderedStringOut:]
15 WebKit -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:]
16 WebKit -[NSString(WebStringDrawing) _web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:]
17 UIKit -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:includeEmoji:]
18 UIKit -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:fontSize:lineBreakMode:baselineAdjustment:includeEmoji:]
19 UIKit -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:fontSize:lineBreakMode:baselineAdjustment:]
20 UIKit -[UILabel _drawTextInRect:baselineCalculationOnly:]
21 UIKit -[UILabel drawTextInRect:]
22 UIKit -[UILabel drawRect:]
23 UIKit -[UIView(CALayerDelegate) drawLayer:inContext:]
24 QuartzCore -[CALayer drawInContext:]
25 QuartzCore backing_callback(CGContext*, void*)
26 QuartzCore CABackingStoreUpdate_
27 QuartzCore CA::Layer::display_()
28 QuartzCore -[CALayer _display]
29 QuartzCore CA::Layer::display()
30 QuartzCore -[CALayer display]
31 QuartzCore CA::Layer::display_if_needed(CA::Transaction*)
32 QuartzCore CA::Context::commit_transaction(CA::Transaction*)
33 QuartzCore CA::Transaction::commit()
34 QuartzCore CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
35 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
36 CoreFoundation __CFRunLoopDoObservers
37 CoreFoundation __CFRunLoopRun
38 CoreFoundation CFRunLoopRunSpecific
39 CoreFoundation CFRunLoopRunInMode
40 GraphicsServices GSEventRunModal
41 GraphicsServices GSEventRun
42 UIKit UIApplicationMain
43 MathProb main /Users/test/MathProb/main.m:14
44 MathProb start

先感谢您。

4

1 回答 1

0

你有 NSZombieEnabled 设置为 YES 吗?我相信这可能会导致误报。验证您没有看到开发环境工件的一种方法是更改​​为发布模式:command+option+R,将运行设置为使用发布模式。然后,运行应用程序。现在,在 iPad 上快速按两次 Home 键,关闭应用程序,然后从主屏幕正常启动它。当以这种方式启动时,我已经看到误报内存泄漏消失了。

于 2012-04-19T05:16:21.460 回答