проблема утечки памяти при использовании NSData в iPhone - PullRequest
5 голосов
/ 09 августа 2009

Проблема утечки памяти - 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];
}

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

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

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

Ответы [ 4 ]

10 голосов
/ 09 августа 2009

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

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 (который установлен на autorelease), скрывающий NSData, выделенный и введенный в строке 1

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

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

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

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

7 голосов
/ 22 октября 2009

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

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

// ** Your Operations **

NSData *data = [NSData dataWithContentsOfURL:someURL];

// ** Your Operation **

[data autorelease];
[pool release];

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

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

7 голосов
/ 07 сентября 2009

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

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

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

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

4 голосов
/ 09 августа 2009

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

Во-вторых. Вам не нужно первое alloc init цепное сообщение. Все, что вам нужно, это:

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

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

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