Экземпляр метода утечки, iPhone - PullRequest
1 голос
/ 06 января 2011

Следующий метод обнаруживается как утечка при выполнении теста на утечку памяти с помощью Инструментов:

- (NSDictionary*) initSigTrkLstWithNiv:(int)pm_SigTrkNiv SigTrkSig:(int)pm_SigTrkSig SigResIdt:(int)pm_SigResIdt SigResVal:(int)pm_SigResVal {
 NSArray *objectArray;
 NSArray *keyArray;
 if (self = [super init]) {
  self.SigTrkNiv = [NSNumber numberWithInt:pm_SigTrkNiv];
  self.SigTrkSig = [NSNumber numberWithInt:pm_SigTrkSig];
  self.SigResIdt = [NSNumber numberWithInt:pm_SigResIdt];
  self.SigResVal = [NSNumber numberWithInt:pm_SigResVal];

  objectArray = [NSArray arrayWithObjects:SigTrkNiv,SigTrkSig,SigResIdt,SigResVal, nil];
  keyArray = [NSArray arrayWithObjects:@"SigTrkNiv", @"SigTrkSig", @"SigResIdt", @"SigResVal", nil];

  self = [NSDictionary dictionaryWithObjects:objectArray forKeys:keyArray];
 }
 return self;
}

код, который вызывает экземпляр:

   NSDictionary *lv_SigTrkLst = [[SigTrkLst alloc]initSigTrkLstWithNiv:[[tempDict objectForKey:@"SigTrkNiv"] intValue]
             SigTrkSig:[[tempDict objectForKey:@"SigTrkSig"]  intValue]
             SigResIdt:[[tempDict objectForKey:@"SigResIdt"]  intValue]
             SigResVal:[[tempDict objectForKey:@"SigResVal"]  intValue]];  
[[QBDataContainer sharedDataContainer].SigTrkLstArray addObject:lv_SigTrkLst];  
[lv_SigTrkLst release];

Инструменты информируют, что SigTrkLstподтекаетДаже если я выпустил экземпляр?(Я знаю, что добавление его в массив увеличивает значение retainCount на 1, но, выпуская его дважды, удаляет его из массива?)

Ответы [ 2 ]

1 голос
/ 06 января 2011

Вы инициализируете экземпляр (self), но затем заменяете его словарем.Предполагая, что это именно то, что вы действительно хотите сделать (см. Часть 2), вам нужно освободить старый self перед назначением нового, а затем вы должны сохранить новый словарь, чтобы ваш метод init сохранил счет сохранения.Обратите внимание, что этот код возвращает объект NSDictionary, когда ваш вызывающий код ожидает SigTrkLst, что почти наверняка является плохой идеей.

- (NSDictionary*) initSigTrkLstWithNiv:(int)pm_SigTrkNiv
                             SigTrkSig:(int)pm_SigTrkSig
                             SigResIdt:(int)pm_SigResIdt
                             SigResVal:(int)pm_SigResVal {
    NSArray *objectArray;
    NSArray *keyArray;
    if (self = [super init]) {   
        self.SigTrkNiv = [NSNumber numberWithInt:pm_SigTrkNiv];
        self.SigTrkSig = [NSNumber numberWithInt:pm_SigTrkSig];
        self.SigResIdt = [NSNumber numberWithInt:pm_SigResIdt];
        self.SigResVal = [NSNumber numberWithInt:pm_SigResVal];
        objectArray = [NSArray arrayWithObjects:
                       SigTrkNiv,SigTrkSig,SigResIdt,SigResVal, nil];
        keyArray = [NSArray arrayWithObjects:
                       @"SigTrkNiv", @"SigTrkSig", @"SigResIdt", @"SigResVal", nil];

        [self release];
        self = [NSDictionary dictionaryWithObjects:objectArray forKeys:keyArray];
        [self retain];
    }
    return self;
}

Часть 2: Что это должно сделать ?Как правило, метод -init... должен возвращать инициализированный экземпляр класса, начиная с выделенного фрагмента памяти.Первая часть вашего -init метода выглядит правильно, кроме возвращаемого значения.Например, следующий метод -init является следующим:

- (id)initSigTrkLstWithNiv:(int)pm_SigTrkNiv
                 SigTrkSig:(int)pm_SigTrkSig
                 SigResIdt:(int)pm_SigResIdt
                 SigResVal:(int)pm_SigResVal {
    if (self = [super init]) {   
        self.SigTrkNiv = [NSNumber numberWithInt:pm_SigTrkNiv];
        self.SigTrkSig = [NSNumber numberWithInt:pm_SigTrkSig];
        self.SigResIdt = [NSNumber numberWithInt:pm_SigResIdt];
        self.SigResVal = [NSNumber numberWithInt:pm_SigResVal];
    }
    return self;
}
0 голосов
/ 06 января 2011
self = [NSDictionary dictionaryWithObjects:objectArray forKeys:keyArray];

Когда вы делаете это, что происходит с объектом SigTrkLst, который сам должен указывать? Разве вы не теряете ссылку на объект SigTrkLst, который был выделен и указан самим собой? Этот объект никогда не освобождается, так как после этой строки нет ссылки на него.

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

РЕДАКТИРОВАТЬ: Кажется, вам не хватает некоторых основ управления памятью для iOS. Я настоятельно прошу вас прочитать Руководство по программированию управления памятью . Это может спасти вас от многих неприятностей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...