iPhone iOS4 内存泄漏?
我有将 UILabel 添加到我的视图的功能:
UILabel* AddLabel(UIView* view,CGRect labelRect, UIStyle* labelStyle, NSString* labelText)
{
UILabel* label = [[[UILabel alloc] initWithFrame:labelRect] autorelease];
label.textColor = [UIColor colorWithCGColor:[ labelStyle.textColor CGColor]];
label.backgroundColor = [UIColor colorWithCGColor:[labelStyle.backgroundColor CGColor]];
label.font =[UIFont fontWithName: labelStyle.fontName] size:labelStyle.fontSize];
label.frame = labelRect;
label.text = labelText;
[view addSubview:label];
return label;
}
其中 UIStyle 有这个接口:
@interface UIStyle : NSObject {
NSString * fontName;
CGFloat fontSize;
UIColor* textColor;
UIColor* backgroundColor;
}
所以当我添加这样的标签到视图时,我会出现内存泄漏。 这是来自 Instruments 的跟踪:
0 libSystem.B.dylib calloc
1 CoreGraphics CGGlyphBitmapCreate
2 CoreGraphics CGFontCreateGlyphBitmap8
3 CoreGraphics CGFontCreateGlyphBitmap
4 CoreGraphics create_missing_bitmaps
5 CoreGraphics CGGlyphLockLockGlyphBitmaps
6 0x317c173f
7 0x317c3e59
8 CoreGraphics CGContextDelegateDrawGlyphs
9 CoreGraphics draw_glyphs
10 CoreGraphics CGContextShowGlyphsWithAdvances
11 WebCore WebCore::Font::drawGlyphs(WebCore::GraphicsContext*, WebCore::SimpleFontData const*, WebCore::GlyphBuffer const&, int, int, WebCore::FloatPoint const&, bool) const
12 WebCore WebCore::Font::drawGlyphBuffer(WebCore::GraphicsContext*, WebCore::GlyphBuffer const&, WebCore::TextRun const&, WebCore::FloatPoint&) const
13 WebCore WebCore::Font::drawSimpleText(WebCore::GraphicsContext*, WebCore::TextRun const&, WebCore::FloatPoint const&, int, int) const
14 WebCore WebCore::Font::drawText(WebCore::GraphicsContext*, WebCore::TextRun const&, WebCore::FloatPoint const&, int, int) const
15 WebCore drawAtPoint(unsigned short const*, int, WebCore::FloatPoint const&, WebCore::Font const&, WebCore::GraphicsContext*, WebCore::BidiStatus*, int)
16 WebCore -[NSString(WebStringDrawing) __web_drawInRect:withFont:ellipsis:alignment:letterSpacing:lineSpacing:includeEmoji:truncationRect:measureOnly:]
17 WebCore -[NSString(WebStringDrawing) _web_drawInRect:withFont:ellipsis:alignment:lineSpacing:includeEmoji:truncationRect:measureOnly:]
18 WebCore -[NSString(WebStringDrawing) _web_drawInRect:withFont:ellipsis:alignment:lineSpacing:includeEmoji:truncationRect:]
19 UIKit -[NSString(UIStringDrawing) _drawInRect:withFont:lineBreakMode:alignment:lineSpacing:includeEmoji:truncationRect:]
20 UIKit -[NSString(UIStringDrawing) drawInRect:withFont:lineBreakMode:alignment:lineSpacing:includeEmoji:]
21 UIKit -[NSString(UIStringDrawing) drawInRect:withFont:lineBreakMode:alignment:lineSpacing:]
22 UIKit -[UILabel _drawTextInRect:baselineCalculationOnly:]
23 UIKit -[UILabel drawTextInRect:]
24 UIKit -[UILabel drawRect:]
25 UIKit -[UIView(CALayerDelegate) drawLayer:inContext:]
26 QuartzCore -[CALayer drawInContext:]
27 QuartzCore backing_callback(CGContext*, void*)
28 QuartzCore CABackingStoreUpdate
29 QuartzCore -[CALayer _display]
30 QuartzCore -[CALayer display]
31 QuartzCore CALayerDisplayIfNeeded
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 -[UIApplication _run]
43 UIKit UIApplicationMain
44 Cuisine main /iPhone/Projects/iCookProFullSix/iCookPrototype/main.m:14
对于函数 AddLabel 的多次调用,我有数百个跟踪。 我这样称呼它:
AddLabel(self.view, CGRectMake(56, 60, 88, 15), style2, @"text");
问题是如果我发表评论 label.font =[UIFont fontWithName: labelStyle.fontName] size:labelStyle.fontSize];
- 没有泄漏..
为什么会这样?这是iOS的错误还是我做错了什么?
PS 此泄漏仅在设备上可见。
有人可以帮忙吗?提前致谢!
I have function for adding UILabel to my view:
UILabel* AddLabel(UIView* view,CGRect labelRect, UIStyle* labelStyle, NSString* labelText)
{
UILabel* label = [[[UILabel alloc] initWithFrame:labelRect] autorelease];
label.textColor = [UIColor colorWithCGColor:[ labelStyle.textColor CGColor]];
label.backgroundColor = [UIColor colorWithCGColor:[labelStyle.backgroundColor CGColor]];
label.font =[UIFont fontWithName: labelStyle.fontName] size:labelStyle.fontSize];
label.frame = labelRect;
label.text = labelText;
[view addSubview:label];
return label;
}
where UIStyle has this interface:
@interface UIStyle : NSObject {
NSString * fontName;
CGFloat fontSize;
UIColor* textColor;
UIColor* backgroundColor;
}
so when I add such label to view, I get memory leak.
Here is the trace from Instruments:
0 libSystem.B.dylib calloc
1 CoreGraphics CGGlyphBitmapCreate
2 CoreGraphics CGFontCreateGlyphBitmap8
3 CoreGraphics CGFontCreateGlyphBitmap
4 CoreGraphics create_missing_bitmaps
5 CoreGraphics CGGlyphLockLockGlyphBitmaps
6 0x317c173f
7 0x317c3e59
8 CoreGraphics CGContextDelegateDrawGlyphs
9 CoreGraphics draw_glyphs
10 CoreGraphics CGContextShowGlyphsWithAdvances
11 WebCore WebCore::Font::drawGlyphs(WebCore::GraphicsContext*, WebCore::SimpleFontData const*, WebCore::GlyphBuffer const&, int, int, WebCore::FloatPoint const&, bool) const
12 WebCore WebCore::Font::drawGlyphBuffer(WebCore::GraphicsContext*, WebCore::GlyphBuffer const&, WebCore::TextRun const&, WebCore::FloatPoint&) const
13 WebCore WebCore::Font::drawSimpleText(WebCore::GraphicsContext*, WebCore::TextRun const&, WebCore::FloatPoint const&, int, int) const
14 WebCore WebCore::Font::drawText(WebCore::GraphicsContext*, WebCore::TextRun const&, WebCore::FloatPoint const&, int, int) const
15 WebCore drawAtPoint(unsigned short const*, int, WebCore::FloatPoint const&, WebCore::Font const&, WebCore::GraphicsContext*, WebCore::BidiStatus*, int)
16 WebCore -[NSString(WebStringDrawing) __web_drawInRect:withFont:ellipsis:alignment:letterSpacing:lineSpacing:includeEmoji:truncationRect:measureOnly:]
17 WebCore -[NSString(WebStringDrawing) _web_drawInRect:withFont:ellipsis:alignment:lineSpacing:includeEmoji:truncationRect:measureOnly:]
18 WebCore -[NSString(WebStringDrawing) _web_drawInRect:withFont:ellipsis:alignment:lineSpacing:includeEmoji:truncationRect:]
19 UIKit -[NSString(UIStringDrawing) _drawInRect:withFont:lineBreakMode:alignment:lineSpacing:includeEmoji:truncationRect:]
20 UIKit -[NSString(UIStringDrawing) drawInRect:withFont:lineBreakMode:alignment:lineSpacing:includeEmoji:]
21 UIKit -[NSString(UIStringDrawing) drawInRect:withFont:lineBreakMode:alignment:lineSpacing:]
22 UIKit -[UILabel _drawTextInRect:baselineCalculationOnly:]
23 UIKit -[UILabel drawTextInRect:]
24 UIKit -[UILabel drawRect:]
25 UIKit -[UIView(CALayerDelegate) drawLayer:inContext:]
26 QuartzCore -[CALayer drawInContext:]
27 QuartzCore backing_callback(CGContext*, void*)
28 QuartzCore CABackingStoreUpdate
29 QuartzCore -[CALayer _display]
30 QuartzCore -[CALayer display]
31 QuartzCore CALayerDisplayIfNeeded
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 -[UIApplication _run]
43 UIKit UIApplicationMain
44 Cuisine main /iPhone/Projects/iCookProFullSix/iCookPrototype/main.m:14
And I have hundreds of them for several calls of function AddLabel.
I call it this way:
AddLabel(self.view, CGRectMake(56, 60, 88, 15), style2, @"text");
The thing is that if I commentlabel.font =[UIFont fontWithName: labelStyle.fontName] size:labelStyle.fontSize];
- there is no leaks..
Why is it so? Is it a bug of iOS or anything I am doing wrong?
P.S. This leak is only visible on device.
Can anybody help? Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
尝试保留返回的 UIfont,然后手动释放它。
我刚刚尝试过这个,它似乎为我解决了这个问题。
Try retaining the UIfont that's returned, and release it manually.
I tried this just now and it seemed to fix it for me.
内存泄漏是由于 UIStyle 类没有正确保留和释放字体名称而导致的。它应该是:
另外,在 UIStyle 实现文件中,该属性应该被合成并在 dealloc 函数中释放。
The memory leak is caused because UIStyle class doesn't retain and release the font name properly. It should be:
Also, in UIStyle implementation file that property should be synthesized and also released in dealloc function.
我的理解是基于阅读 UIFont文档的优点是字体对象在内部缓存,以便将来对相同字体的查找可以更快地进行。我确信内存损失相当小,并且潜在的泄漏似乎实际上是设计使然,因此无需担心。
My understanding, based on a reading of the UIFont documentation, is that font objects are cached internally so that future lookups for an identical font can proceed more quickly. I'm sure the loss in memory is fairly minor, and the would-be leak seems to actually be by design, so it's not anything to worry about.
除非您创建的每个
UIFont
都发生这种泄漏,否则无需担心 - 操作系统会在您的应用程序退出时清除泄漏。如果每次创建
UIFont
时都会发生这种情况,那么您的UIStyle
类(顺便说一下,它与 Apple 的命名空间冲突)应该缓存UIFont
重新创建它。另外,您不需要
[UIColor colorWithCGColor:[labelStyle.textColor CGColor]]
位,您只需分配labelStyle.textColor
Unless this leak occurs for every
UIFont
you create, it's not something to worry about--the OS will cleanup the leak when your application exits.If it occurs each time a
UIFont
is created, perhaps yourUIStyle
class (which collides with Apple's namespace by the way) should cache theUIFont
instead of having it recreated.Also, you don't need the
[UIColor colorWithCGColor:[labelStyle.textColor CGColor]]
bit, you can just assignlabelStyle.textColor