Изменяемая копия NSData в NSMutableDIctionary вызывает утечку памяти - PullRequest
0 голосов
/ 17 марта 2011

В моем коде я определяю NSDictionary в viewDidAppear следующим образом:

dataDictionary = [[NSMutableDictionary alloc] init];

затем позже в методе loadDataЯ загружаю изменяемую копию NSDictionary следующим образом:

      [dataDictionary setObject:[receivedData mutableCopy] forKey:[theConnection description]];

Позже, когда я переключаюсь в другое представление, я выгружаю свой dataDictionary для экономии памяти.В viewDidDissappear я помещаю:

[выпуск dataDictionary];dataDictionary = nil;

и я также освобождаю dataDictionary в dealloc.

Однако, похоже, что произошла утечка памяти, связанная с mutableCopy, и это единственная mutableCopy, которую я делаю, так что это должно быть из mutableCopy, показанного выше.Кто-нибудь знает, почему это может протекать?Я думаю, что mutableCopy делает другое распределение помимо выделения, сделанного для NSMutableDictionary, но я не уверен, как с этим справиться, так как mutableCopy находится внутри словаря, и словарь выпущен.

Заранее спасибо...

Ответы [ 3 ]

4 голосов
/ 17 марта 2011

метод mutableCopy не возвращает автоматически выпущенный объект, поэтому вы получаете NSMutableData со счетом сохранения 1, а затем добавляете его в словарь, который также сохраняет его - это означает, что он не будет уничтожен при его удалении из словаря или когда словарь освобожден, вы потеряете любую ссылку на него, и объект будет утек.

так что, как кто-то другой предложил, автоматически высвобождать изменяемую копию при добавлении ее в dataDictionary.

[dataDictionary setObject:[[receivedData mutableCopy] autorelease] forKey:[theConnection description]];

или сделать что-то вроде

NSMutableData *mutableData = [receivedData mutableCopy];
[dataDictionary setObject:mutableData forKey:[theConnection description]];
[mutableData release];
1 голос
/ 17 марта 2011

Попробуйте что-то вроде этого

[dataDictionary setObject:[[receivedData mutableCopy] autorelease] forKey:[theConnection description]];
0 голосов
/ 17 марта 2011

Как уже упоминали Бендж и Заки, вы должны вызывать autorelease на mutableCopy, но вы также должны быть уверены, что не выпускаете dataDictionary как в dealloc, так и в viewDidDisappear :. Поскольку dataDictionary имеет счет сохранения 1, когда вы его создаете, и оба viewDidDisappear: и dealloc, вероятно, вызываются при разрушении вашего представления, вы в конечном итоге попытаетесь освободить объект, который уже был освобожден.

Убедитесь, что вы выпускаете dataDictionary только в dealloc, и вы не увидите упомянутое вами сообщение об ошибке "double free". Вызов «release» на ivar в viewDidDisappear: в любом случае, является рискованным предложением, так как viewDidDisappear: вызывается несколько раз в течение жизненного цикла представления (например, если другие контроллеры представления помещаются в ваш стек навигации). Если вы хотите сэкономить память, лучше всего создавать вещи в viewDidLoad и выпускать вещи в viewDidUnload. viewDidUnload вызывается в ситуациях нехватки памяти, так что это именно то, что вы хотите в этой ситуации.

Возможно, вы захотите проверить этот пост для подробного описания соглашений о подсчете ссылок Какао: Владение объектом в stringWithString и initWithString в NSString

...