проблема утечки памяти с использованием NSData в iPhone

Проблема утечки памяти - NSConcreteData

// to set tip - photo in photo frame    
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:pathOfThumbNail]];
UIImage *cellThumbImg;
if([data length]>0){ cellThumbImg=[UIImage imageWithData:data];} else { cellThumbImg=[UIImage imageNamed:@"130X90.gif"]; }
UIImageView *imgView=[[UIImageView alloc]initWithImage:cellThumbImg]; imgView.frame=photoFrame;
(cellThumbImg.size.height>=58 || cellThumbImg.size.width>=58 ) ? [imgView setContentMode:UIViewContentModeScaleToFill] : [imgView setContentMode:UIViewContentModeCenter] ;
[cell.contentView addSubview:imgView]; 
[imgView release]; 

мой вопрос очень похож на этот вопрос,

iPhone - утечка памяти - NSData dataWithContentsOfUrl & UIWebView

Даже я добавил следующий код в свое приложение, завершившее запуск, приведенное ниже. Следующий код предназначен для установки памяти sharedCache с нулевым объемом. Это почти устранит утечку NSConcreteData в моем приложении. Однако утечки памяти.

- (void)applicationDidFinishLaunching:(UIApplication *)application {       
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];
[window makeKeyAndVisible];
}

Я не мог найти решения для такого рода вопросов из-за переполнения стека.

Если вы ответите, я буду вам благодарен.

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


person Sagar R. Kothari    schedule 08.08.2009    source источник
comment
Я пошел по пути как @Bkaenk & @epatelsaid. Однако возникает та же проблема, что и в следующем вопросе. stackoverflow.com/questions/280053/   -  person Sagar R. Kothari    schedule 09.08.2009


Ответы (4)


У меня тоже были проблемы с этим в моем большом проекте. Поработав с инженером Apple над поиском утечек, он наконец спросил у основной команды разработчиков Apple, стоящей за NSURLConnection. По сути, они сказали, что в NSURLConnection есть внутренний кеш, который невозможно очистить, и это известная проблема.

Поэтому я начал искать альтернативы. Я нашел ASIHTTPConnection (ссылка ниже), который работает вне CFNetwork. Он предназначен для замены NSURLConnection, а также для множества других замечательных вещей, таких как загрузка на диск вместо памяти, возобновление загрузки, обратные вызовы индикатора выполнения и т. Д.

Я использовал его во всех своих проектах, и у меня никогда не было проблем или жалоб. Отвечая на ваш вопрос, вот как я избавился от утечек памяти.

http://allseeing-i.com/ASIHTTPRequest/

person coneybeare    schedule 07.09.2009
comment
Хотя это принятый ответ и, вероятно, проблема OP решена, я упустил из виду более простое решение в ответе epatel. Его ответ должен быть принятым. - person coneybeare; 19.08.2011

У вас есть три строки, давайте разберем их

1. NSData *imageData = [[NSData alloc] init];
2. imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"www.xyz.abc.com"]];
3. [imageData release];

Строка 1: выделить и инициализировать новые NSData. У этого NSData будет счетчик ссылок +1

Строка 2: получить данные из Интернета и поместить в NSData. Это устанавливает переменную, используемую в строке 1, в новую NSData (которая настроена на автозапуск), скрывая выделенные и инициированные NSData в строке 1.

Строка 3: выпустит NSData, полученные на Строке 2.

Вы можете удалить Строку 1 и 3 и просто добавить объявление переменной в Строку 2. Поскольку она запускается автоматически, она будет выпущена петлей событий позже ...

NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"www.xyz.abc.com"]];

Предлагаю вам прочитать здесь разделы Управление памятью.

person epatel    schedule 08.08.2009
comment
@ePatel - Сэр, пожалуйста, ознакомьтесь с исправлением в моем вопросе. Я с той же проблемой. Даже после применения предложенной вами логики я обнаружил ту же проблему с утечкой памяти. - person Sagar R. Kothari; 02.09.2009
comment
Nit: строка 2 скрывает только что выделенные / инициализированные данные imageData, создавая новый. - person Kaolin Fire; 18.06.2012
comment
Я, видимо, придурок, извините. Я искал это в ваших комментариях, но пропустил и сделал плохое предположение на основе отредактированного вопроса .... - person Kaolin Fire; 19.06.2012

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

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// ** Your Operations **

NSData *data = [NSData dataWithContentsOfURL:someURL];

// ** Your Operation **

[data autorelease];
[pool release];

Это относится даже к NSURLRequest и NSURLConnection.

Проблема заключается в самом компиляторе, и описанный выше единственный способ решить эту проблему.

person Community    schedule 22.10.2009
comment
Это абсолютно неверно. Вы не сохранили объект ни с одним из retain, alloc, copy, mutableCopy или new. Вы не имеете права autorelease это делать. Это неверно и приведет к сбою вашей программы где-нибудь в будущем. - person user102008; 15.06.2012

Ваше сообщение о выпуске написано неправильно, вы набрали relaese, но это release. Я полагаю, что это просто проблема в коде, который вы ввели для этого вопроса.

Второй. Вам не нужно первое alloc init сообщение цепочки. Все что тебе нужно это:

NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"www.xyz.abc.com"]];

Конечно, я не знаю, действительно ли этот вызов верен, но я знаю, что он возвращает автоматически выпущенный объект NSData, что означает, что ваш предыдущий alloc init будет протекать.

person Jorge Israel Peña    schedule 08.08.2009
comment
@Blaenk - Сэр, проверьте исправление в моем вопросе. Я с той же проблемой. Даже после применения предложенной вами логики я обнаружил ту же проблему с утечкой памяти. - person Sagar R. Kothari; 02.09.2009