утечка памяти на iPhone iOS4? - PullRequest
4 голосов
/ 14 июля 2010

У меня есть функция для добавления 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;
}

поэтому, когда я добавляю такую ​​метку для просмотра, я получаю утечку памяти. Вот след от инструментов:

   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 или я что-то не так делаю?

P.S. Эта утечка видна только на устройстве.

Кто-нибудь может помочь? Заранее спасибо!

Ответы [ 4 ]

1 голос
/ 14 июля 2010

Если эта утечка не возникает для каждого UIFont, который вы создаете, беспокоиться не о чем - ОС устранит утечку при выходе из приложения.

Если это происходит каждый раз, когда UIFontсозданный, возможно, ваш UIStyle класс (который, кстати, сталкивается с пространством имен Apple) должен кэшировать UIFont вместо его воссоздания.

Кроме того, вам не нужен бит [UIColor colorWithCGColor:[labelStyle.textColor CGColor]], выможно просто назначить labelStyle.textColor

0 голосов
/ 22 ноября 2010

Мое понимание, основанное на прочтении документации UIFont , заключается в том, что объекты шрифтов кэшируются внутри, чтобы в будущем поиск идентичного шрифта мог выполняться быстрее. Я уверен, что потеря памяти довольно незначительна, и потенциальная утечка, похоже, на самом деле имеет место, поэтому беспокоиться не о чем.

0 голосов
/ 17 ноября 2010

Утечка памяти вызвана тем, что класс UIStyle не сохраняет и не освобождает имя шрифта должным образом. Должно быть:

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

Кроме того, в файле реализации UIStyle это свойство должно быть синтезировано и также освобождено в функции dealloc.

0 голосов
/ 15 июля 2010

Попробуйте сохранить возвращенный UIfont и отпустите его вручную.

Я попробовал это только сейчас, и мне показалось, что это исправлено.

...