iPhone iOS4 内存泄漏?

发布于 2024-09-10 00:05:35 字数 4250 浏览 1 评论 0原文

我有将 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 comment
label.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

七度光 2024-09-17 00:05:37

尝试保留返回的 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.

雨落星ぅ辰 2024-09-17 00:05:37

内存泄漏是由于 UIStyle 类没有正确保留和释放字体名称而导致的。它应该是:

@interface UIStyle : NSObject {
  NSString * fontName;
  CGFloat fontSize;
  UIColor* textColor;
  UIColor* backgroundColor;
}
@property(nonatomic, retain) NSString* fontName;
...

另外,在 UIStyle 实现文件中,该属性应该被合成并在 dealloc 函数中释放。

The memory leak is caused because UIStyle class doesn't retain and release the font name properly. It should be:

@interface UIStyle : NSObject {
  NSString * fontName;
  CGFloat fontSize;
  UIColor* textColor;
  UIColor* backgroundColor;
}
@property(nonatomic, retain) NSString* fontName;
...

Also, in UIStyle implementation file that property should be synthesized and also released in dealloc function.

-柠檬树下少年和吉他 2024-09-17 00:05:37

我的理解是基于阅读 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.

蓬勃野心 2024-09-17 00:05:36

除非您创建的每个 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 your UIStyle class (which collides with Apple's namespace by the way) should cache the UIFont instead of having it recreated.

Also, you don't need the [UIColor colorWithCGColor:[labelStyle.textColor CGColor]] bit, you can just assign labelStyle.textColor

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文