#memory-leaks #uiimage #nsdata #instruments #nsautoreleasepool
#утечки памяти #uiimage #nsdata #инструменты #nsautoreleasepool
Вопрос:
С помощью инструментов у меня произошла утечка памяти в этом фрагменте кода, и я не понимаю, почему!
-(void)goToThisUrl:(id) targetUrl
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (someCondition) {
// Doing some stuff here
}
// Instruments show memory leak on data
else {
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString: targetUrl]];
myTargetImage = [UIImage imageWithData:data];
// When releasing data(because data retainCount = 2), i got:
// Incorrect decrement of the reference count of an object that is not owned at this point by the caller
//[data release];
}
[pool release];
}
Спасибо
Комментарии:
1. Вы делаете это для отдельного потока, верно?
2. Да, именно поэтому я выделяю NSAutoreleasePool для этого метода 🙂
Ответ №1:
В приведенном выше примере утечки нет. Могут быть одна или несколько утечек в частях, которые вы удалили и заменили «someCondition» и «Делаем здесь кое-что», но никто здесь не сможет помочь с этим, если вы не опубликуете полный код, который вы действительно тестируете с помощью инструментов.
Также: «// При выпуске данных (поскольку количество сохраняемых данных = 2) …» Остановка. Верно. Там. Игнорировать сохранение количества. Вы освобождаете объект, потому что вы создали его, используя метод, который подразумевает владение, или потому что вы сохранили его. Вы НИКОГДА не освобождаете объект только потому, что его значение retainCount имеет значение, которого вы не ожидали или не понимаете. Подробнее ознакомьтесь с руководством Apple по программированию управления памятью.
Ответ №2:
Во-первых, вы не можете выделить UIImage во втором потоке. Использование UIKit должно осуществляться в основном потоке. Я предполагаю, что вы хотели сделать, создав другой поток, чтобы вызвать dataWithContentsOfURL, не блокируя основной поток. Но это неправильный подход. Вместо этого используйте NSURLConnection с асинхронным обратным вызовом, который вызывается по завершении загрузки. Apple уже предоставляет встроенный поток «загрузки», который NSURLConnection использует за кулисами. Итак, ваш подход к созданию другого потока для загрузки бессмыслен.