[NSDate descriptionWithLocale: [NSLocale systemLocale]] утечка? - PullRequest
2 голосов
/ 05 июля 2011

enter image description here При использовании инструментов я обнаружил странную проблему с утечками памяти.Мое приложение имеет механизм журнала, который записывает события через приложение и весь обмен данными с сервером (запрос-ответ).Каждый записанный объект события имеет метку времени.Эта временная метка получается следующим образом:

[NSDate descriptionWithLocale:[NSLocale systemLocale]]

Используя приборы, я увидел, что описание с локальными причинами вызывает утечку.

Ниже приведен код:

-(id)initEvent:(NSString*)eventStr details:(NSString*)detailsStr{
     eventString = [[NSMutableString alloc] initWithString:eventStr];
     detailsString = [[NSString alloc] initWithString:detailsStr];
     date =[[NSMutableString alloc] init];
     NSDate* currentDate = [NSDate date];    
     NSString *dateDescStr = [currentDate descriptionWithLocale:[NSLocale systemLocale]];
      [date appendString:dateDescStr];  

    return [super init];

Спасибо, Алекс.

Ответы [ 2 ]

1 голос
/ 05 июля 2011

Вы уверены, что descriptionWithLocale вызывает утечку памяти? Вы не используете свойство accessor / mutator для установки свойств вашего класса, и вы освобождаете их в методе, отличном от вашего dealloc метода, который будет вызывать проблемы. По крайней мере, вы нарушаете основные правила управления памятью, выделяя eventString, detailsString и date в initEvent (который затем является владельцем, поскольку вы не используете аксессор / мутатор свойств) и выпустить их в методе eventDictionary, который не является владельцем.

Я бы начал со следующей попытки (при условии, что все ваши свойства имеют атрибут retain):

-(id)initEvent:(NSString*)eventStr details:(NSString*)detailsStr{
     this.eventString = [[NSMutableString alloc] initWithString:eventStr];
     this.detailsString = [[NSString alloc] initWithString:detailsStr];
     this.date =[[NSMutableString alloc] init];
     NSDate* currentDate = [NSDate date];    
     NSString *dateDescStr = [currentDate descriptionWithLocale:[NSLocale systemLocale]];
      [date appendString:dateDescStr];  
     [eventString release];
     [detailsString release];
     [date release];

    return [super init];
}

Также удалите вызовы освобождения из eventDictionary и добавьте их в метод dealloc в соответствии со стандартным шаблоном управления памятью.

Попробуйте и посмотрите, поможет ли это. Дайте мне знать, если я смогу что-то уточнить.

0 голосов
/ 06 июля 2011

Спасибо за ваше решение.Работает отлично.На самом деле причиной утечки была не descriptionWithLocale, а моя собственная реализация правила памяти (было 1 год назад :(). Странно, что инструменты указывали на вызов этого метода .... Посмотрите, как теперь выглядит мой класс:

@implementation EventItem
@synthesize eventString, detailsString, date;


-(id)initEvent:(NSString*)eventStr details:(NSString*)detailsStr{

    if((self = [super init])){
      self.eventString = [[NSMutableString alloc] initWithString:eventStr];
      self.detailsString = [[NSString alloc] initWithString:detailsStr];
      self.date =[[NSMutableString alloc] init];
      NSDate* currentDate = [NSDate date];    
      NSString *dateDescStr = [currentDate descriptionWithLocale:[NSLocale systemLocale]];
      [date appendString:dateDescStr];      
      [eventString release];
      [detailsString release];
      [date release];
  }

  return self;
}

-(NSMutableDictionary*)eventDictionary{
    if(!dictionary)
       dictionary = [[NSMutableDictionary alloc] init];
    else
        return dictionary;

   [dictionary setObject:self.date forKey:@"Event"];
   [dictionary setObject:self.date forKey:@"Date"];
   [dictionary setObject:self.detailsString forKey:@"Details"];
   [dictionary setObject:self.eventString forKey:@"EventDescription"];

   return [dictionary autorelease];
 }

-(void)dealloc{     
    // NSLog(@"dealloc called in EventItem");

   [eventString release];
   [detailsString release];
   [date release];

   [super dealloc]; 
}


@end

Теперь еще одна проблема, которая у меня возникла, связана с тем, что какое-то изображение загружается через "loadWithContentsOfFile:"

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.tableView.rowHeight = OC_CELL_HEIGHT;
    self.tableView.backgroundColor = [UIColor clearColor];

    UIImage* backgroundImage = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"TableBg" ofType:@"png"]];
    UIImageView* background = [[UIImageView alloc] initWithFrame:self.tableView.frame];
    background.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    background.image = backgroundImage;
    [background sizeToFit];
    [backgroundImage release];
    [self.tableView setBackgroundView:background];
    [background release];
    [self.tableView setAutoresizesSubviews:YES];
    selectedOCData = nil;
    self.tableView.autoresizingMask =  UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
}

В строке:

 UIImage* backgroundImage = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"TableBg" ofType:@"png"]];

просачивается 98%, а самая тяжелаяобратная трассировка составляет 240 КБ. Я приложил скриншот с инструментами для этого. Есть ли проблема не с фактическим вызовом initWithContentsOfFile, а с tableView, который не освобожден правильно? (Мой класс - tableViewController).

Спасибо, Алекс. instruments

...