开发者

memory leak on iPhone iOS4?

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::开发者_JS百科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!


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


Try retaining the UIfont that's returned, and release it manually.

I tried this just now and it seemed to fix it for me.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜