NSURLConnection портит память iPad - PullRequest
2 голосов
/ 01 марта 2012

мы создаем приложение для iPad, которое загружает кучу данных и PDF-документы из веб-службы (сначала данные, затем документы в фоновом режиме).Для этого мы используем SOAP через HTTP (S) запросы.Работает нормально и в целом приложение работает хорошо.Проблема в том, что если в какой-то момент приложение загружает слишком много документов, происходит сбой приложения.Используя инструменты, я понял, что это проблема с памятью, особенно NSRegularExpression и NSRunLoop.(Я использую ARC)

Я мог бы улучшить свой код, чтобы оптимизировать создание NSRegularExpression.Но я не знаю, как улучшить проблему NSRunLoop.

Я пробовал как асинхронный, так и синхронный HTTP-запрос.Используя async, мне пришлось ждать окончания загрузки, и поскольку sleep () / [NSThread sleepForTimeInterval:] не вариант, я использую

while ( _waitToFinish ) {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}

Используя запрос синхронизации, Instruments показывает, что

[NSURLConnection sendSynchronousRequest:theRequest returningResponse:&urlResponse error:&error];

также "ждет" с помощью NSRunLoop и также портит память.

Это ошибка в CoreFoundation или ARC?

Есть ли другой способ простоя во время ожиданияза завершение запросов?

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

Редактировать:

Под "проблемой памяти" я имел ввиду, что приложение вылетает (илиубит iOS), потому что он использует слишком много памяти.

Это то, что показывают инструменты: Instruments screenshot Чем выше процент, тем дольше загружается приложение.

Редактировать:

Идя дальше, мы обнаружили, что NSURLConnection портит память.Кажется, я как-то пропустил установку connection и receivedData на nil (см. Руководство по программированию системы загрузки URL ).Это немного улучшило мое использование памяти.

Теперь есть еще две большие операции выделения памяти: enter image description here

И этот код, я думаю, принадлежит тому, что отображает Instruments:

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [_receivedData appendData:data];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {    
    NSString *responseText = [[NSString alloc] initWithBytes:[_receivedData mutableBytes] length:[_receivedData length] encoding:NSUTF8StringEncoding];

    self.lastResponse = responseText;

    responseText = nil;
    connection = nil;
    _receivedData = nil;

    _lastResult = TRUE;
    _waitToFinish = FALSE;
}

Могу ли я что-нибудь изменить, чтобы улучшить код?

Редактировать: (изменено название с "NSRunLoop портит память iPad")

Редактировать: Я создал тестовое приложение, чтобы доказать, что это NSURLConnection, который портит память.Затем я связался со службой поддержки разработчиков Apple.

Поскольку я загружаю много PDF-файлов в итерации с NSURLConnection, было решено добавить @autoreleasepool { .. } в итерации и еще один вокруг NSRunLoop.

Спасибо.

1 Ответ

1 голос
/ 01 марта 2012

Это не ошибка в Core Foundation или ARC.Это ошибка в вашем коде.

Не запускайте цикл выполнения самостоятельно.Просто используйте +[NSURLConnection sendAsynchronousRequest:queue:completionHandler:].Он вызовет ваш блок completionHandler, когда запрос будет завершен.Вот когда вы обрабатываете ответ.Между тем, просто вернитесь из своего метода и позвольте системе беспокоиться о запуске цикла выполнения.

Вы говорите «это проблема памяти» с NSRegularExpression и NSRunLoop, но вы не говорите, чтовопрос, или какие доказательства Инструменты показывают вам.Если вы опишите «проблему» более подробно, возможно, мы сможем вам в этом помочь.

...