【问题标题】:memory leak on iPhone iOS4?iPhone iOS4内存泄漏?
【发布时间】:2011-03-15 21:48:45
【问题描述】:

我有将 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的错误还是我做错了什么?

附:此泄漏仅在设备上可见。

有人可以帮忙吗?提前致谢!

【问题讨论】:

  • 我也遇到了类似的泄漏,它也只发生在设备上而不是模拟器上。
  • 对代码运行 clang 静态分析器可能会帮助您定位问题。
  • 感谢您的评论,但我用clang检查了该应用程序,它没有显示任何内容。

标签: iphone objective-c memory-leaks uifont


【解决方案1】:

除非您创建的每个UIFont 都发生这种泄漏,否则不必担心——操作系统会在您的应用程序退出时清除泄漏。

如果每次创建 UIFont 时都会发生这种情况,那么您的 UIStyle 类(顺便说一下与 Apple 的命名空间冲突)可能应该缓存 UIFont 而不是重新创建它。

另外,你不需要[UIColor colorWithCGColor:[labelStyle.textColor CGColor]] 位,你可以分配labelStyle.textColor

【讨论】:

  • 感谢您的回答。我会检查您的建议是否有帮助!
【解决方案2】:

尝试保留返回的 UIfont,然后手动释放它。

我刚刚尝试了这个,它似乎为我解决了这个问题。

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

      基于对UIFont documentation 的阅读,我的理解是字体对象在内部缓存,以便将来查找相同字体可以更快地进行。我敢肯定内存损失是相当轻微的,而且可能的泄漏似乎实际上是设计使然,所以不必担心。

      【讨论】:

        猜你喜欢
        • 2011-03-15
        • 2010-11-23
        • 2011-12-10
        • 2011-05-24
        • 2023-03-20
        • 1970-01-01
        相关资源
        最近更新 更多