2012-06-06 4 views
2

У меня есть простой способ в моей модели создать объект NSDictionary, содержащий его свойства. К сожалению, этот метод рассматривается как «Анализируемый» для утечки памяти:Ошибка утечки памяти

Потенциальная утечка памяти объекта, выделенного по линии 76 (обозначенная здесь точкой), и хранится в «dic».

-(NSDictionary*) getDictionary { 
    NSDictionary *dic = [[NSDictionary alloc] init]; 

    [dic setValue:(id)self.internal_code forKey:@"internal_code"]; 
    [dic setValue:(id)self.identifier forKey:@"id"]; 
    [dic setValue:(id)self.owner forKey:@"owner"]; 
    [dic setValue:(id)self.address forKey:@"address"]; 
    [dic setValue:(id)self.displayed_name forKey:@"displayed_name"]; 

    return dic; 
} 

Я не использую ARC.

PS: Для людей, которые пришли, исходный код, который я опубликовал, был правильным - у него была автореферат. Я отредактировал его после того, как возникнет утечка памяти и спросит, почему именно.

+3

Как этот код может работать? Вы пытаетесь установить значение в NSDictionary. Вы не можете сделать это. – Apurv

+0

Просто несвязанный совет. Вы можете сделать ваш alloc/init/autorelease в просто '[NSDictionary dictionary]'. У многих стандартных классов есть такие конструкторы удобства. –

+0

Также вы говорите, что строка 76 является вашим экземпляром nsdictionary, но я думал, что это было dic.В нем говорится, что утечка хранится в dic, и вы не храните словарь самостоятельно –

ответ

0

При возврате объекта из метода, который не начинается с alloc, copy, mutableCopy или new, что объект должен быть возвращен в autoreleased.

Более концептуально, это не должно быть принадлежало вашим кодом при его возврате. Вы приобретаете право собственности на объект при вводе alloc, copy, mutableCopy или new. Вы отказываетесь от права собственности при вводе release или autorelease.

Вы можете изменить обратное заявление:

return [dic autorelease]; 

или лучше держать alloc/init/autorelease все на одной линии, поэтому код легче рассмотреть, и Alloc и освобождение не могут стать отделенный случайно во время копирования и вставки кода:

NSDictionary *dic = [[[NSDictionary alloc] init] autorelease]; 

еще проще это использовать этот конструктор удобства на NSDictionary:

NSDictionary *dic = [NSDictionary dictionary]; 

Вышеуказанные строки исправят утечку памяти. Тем не менее, вы также пытаетесь изменить неизменяемый тип (NSDictionary). Вы должны использовать изменяемый словарь вместо:

NSMutableDictionary *dic = [NSMutableDictionary dictionary]; 

Наконец, вы должны быть в идеале установка значения с помощью метода setObject:forKey:, хотя setValue:forKey: также будет работать.

Для получения дополнительной информации об управлении памятью читайте Advanced Memory Management Programming Guide.

Если вы нацеливаете iOS 4 или новее, я настоятельно рекомендую использовать ARC.

+0

Хорошо, действительно, NSDictionary не был действительно умным. Кажется странным назвать авторекламу на объекте, который будет использовать какой-то другой метод, но я думаю, что я должен просто привыкнуть к нему. Спасибо за все советы и правильный ответ! – dvkch

+0

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

0

Попробуйте autorelease при возвращении в DIC, как показано ниже

return[dic autorelease]; 
+0

Нет, это не будет иметь никакого значения. – Krishnabhadra

+0

Это было бы неправильно. Объект создается уже как автореализованный. Снова сбросить его неправильно. –

+0

Извините, была ошибка: я не пользовался авторефератом. Я исправил код в своем Вопросе. – dvkch

Смежные вопросы