NSURLCподключение утечки? - PullRequest
       15

NSURLCподключение утечки?

9 голосов
/ 28 августа 2009

Я настроил nsurl, который получает данные с http. когда я запускаю прибор, он говорит, что у меня есть объект утечки NSFNetwork.

и как мне отпустить theConnection in (void) ButtonClicked? или это будет позже?

- (void)ButtonClicked {
    NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:KmlUrl]
                                                cachePolicy:NSURLRequestUseProtocolCachePolicy
                                            timeoutInterval:20.0f];

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
    if (theConnection) {
        // receivedData is declared as a method instance elsewhere
        NSMutableData *receivedData = [[NSMutableData data] retain];
        [self setKMLdata:receivedData];
    } else {
        // inform the user that the download could not be made
    }
}


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // append the new data to the receivedData
    // receivedData is declared as a method instance elsewhere
    [KMLdata appendData:data];
    NSLog(@"didReceiveData");
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // release the connection, and the data object
    [connection release];
    [KMLdata release];
}


- (void)connection:(NSURLConnection *)connection  didFailWithError:(NSError *)error
{
    // release the connection, and the data object
    [connection release];
    // receivedData is declared as a method instance elsewhere
    [KMLdata release];

}

Ответы [ 4 ]

17 голосов
/ 09 декабря 2009

Я наконец нашел ответ на этот вопрос.

Ошибка в приведенном выше коде (который, кстати, является почти точным образцом из SDK документации ) отсутствует в коде управления памятью. Авторелиз - это один из вариантов, ручной выпуск - другой. Независимо от того, как вы обрабатываете объект NSURLConnection, вы получаете утечки, используя NSURLConnection.

Прежде всего, вот решение. Просто скопируйте эти 3 строки кода непосредственно в connectionDidFinishLoading, didFailWithError и в любое другое место, где вы выпускаете объект NSURLConnection.

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];

Кредит mpramodjain на http://forums.macrumors.com/showthread.php?t=573253 для кода.

Проблема, похоже, в следующем - SDK кэширует запросы и ответы на iPhone. Даже если ваш NSMutableURLRequest cachePolicy настроен так, чтобы не загружать ответ из кэша.

Глупо то, что кажется, что по умолчанию кэшируется много данных. Я передаю много данных (разбитых на несколько соединений) и начал получать предупреждения памяти, и, наконец, мое приложение умерло.

Документы, которые нам нужны, находятся в NSURLCache (не NSURLConnection), они утверждают:

NSURLCache реализует кэширование ответы на запросы загрузки URL по отображение объектов NSURLRequest на NSCachedURLResponse объекты. Это композит из памяти и кэш на диске.

Методы предоставляются для управления размеры каждого из этих кэшей, а также как контролировать путь на диске для использования для постоянного хранения данных кеша.

Эти три строки полностью уничтожают кеш. После добавления их в мое приложение ( Журнал GPS ) число моих живых объектов остается неизменным.

5 голосов
/ 24 июля 2011

Здравствуйте, вы тестировали этот метод делегата?

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
    return nil;
}

Вы можете более точно управлять кешем.

"сбросить" NSURLCache * sharedCache может вызвать проблемы с другой частью вашего кода?

2 голосов
/ 28 августа 2009

Это распространенный вопрос, и он решается магией [autorelease объекта]. В вашем коде это будет выглядеть следующим образом:

NSURLConnection *theConnection = [[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];

Таким образом, объект автоматически добавляется в «пул автоматического выпуска» и освобождается в начале следующего цикла выполнения после того, как на него больше не ссылаются.

Надеюсь, что помогает

Редактировать: Кроме того, я не понимаю, зачем вам нужно вызывать -retain для вашей переменной selectedData.

1 голос
/ 07 января 2012

Я использую метод static / autoreleased, и он работает нормально:

[NSURLConnection connectionWithRequest:theRequest delegate:self];

Таким образом, вам даже не нужно беспокоиться об освобождении в обратных вызовах делегата. Оказывается, что счетчик сохранения соединения фактически равен 2 (а не 1) после того, как он был выделен в приведенных выше примерах, что меняет способ, которым я думал об этой утечке памяти.

@ rpetrich Я на самом деле не думаю, что вам нужно беспокоиться об освобождении делегата до того, как будет установлено соединение. Соединение сохраняет свой делегат, а само соединение фактически сохраняется в какой-то очереди открытых соединений. Я написал сообщение в блоге о моих экспериментах с NSURLConnection в моем блоге:

«Потенциальная утечка объекта» с NSURLConnection

...