Как правильно освободить объекты NSMutableDictionary, скопированные из одного массива в другой? - PullRequest
0 голосов
/ 02 ноября 2011

В следующем коде я хочу пройти NSMutableArray (self.codes), который содержит объекты NSMutableDictionary.Если значение ключа «selected» равно «1», я хочу скопировать объект «code» NSMutableDictionary и добавить его в массив selectedCodes.

1  -(NSMutableArray *)getSelecedCodes{
2  
3  NSMutableArray *selectedCodes=[[NSMutableArray alloc]init];
4  
5  for (NSMutableDictionary *code in self.codes) {
6    if([code valueForKey:@"selected"]==@"1"){
7      [selectedCodes addObject:[code copy]];
8    }
9  }
10
11 return selectedCodes;
12
13 }

Когда я анализирую код в XCodeЯ получаю предупреждение о возможных утечках памяти.Есть мысли о том, что я делаю не так?

Ответы [ 2 ]

3 голосов
/ 02 ноября 2011

-[NSMutableArray addObject:] сохраняет свой аргумент. copy также возвращает оставшееся значение. Таким образом, вы сохраняете скопированный словарь дважды .

Вы, вероятно, хотите сделать это:

[selectedCodes addObject:[[code copy] autorelease]];

Однако, в зависимости от ваших конкретных потребностей, есть несколько предостережений:

  1. Вы уверены, что хотите скопировать словарь? Вы можете просто добавить его в массив:

    [selectedCodes addObject:code];

    Обратите внимание, что и selectedCodes, и self.codes будут содержать указатели на один и тот же словарь, поэтому изменения в одной копии будут отражаться и в другой.

  2. Возможно, вы захотите создать изменчивую копию словаря. copy возвращает неизменный объект:

    [selectedCodes addObject:[[code mutableCopy] autorelease]];

3 голосов
/ 02 ноября 2011

Вы должны автоматически высвобождать скопированный объект при его добавлении

for (NSMutableDictionary *code in self.codes) {
    if([code valueForKey:@"selected"]==@"1"){
        [selectedCodes addObject:[[code copy] autorelease]];  
    }
}

Вы должны также использовать методы сравнения строк, в отличие от простого сравнения указателей:

[code valueForKey:@"selected"]==@"1"

никогда не будет правдой, вместо этого используйте

[[code valueForKey:@"selected"] isEqualToString:@"1"]
...