мы создаем приложение для 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), потому что он использует слишком много памяти.
Это то, что показывают инструменты: Чем выше процент, тем дольше загружается приложение.
Редактировать:
Идя дальше, мы обнаружили, что NSURLConnection портит память.Кажется, я как-то пропустил установку connection
и receivedData
на nil
(см. Руководство по программированию системы загрузки URL ).Это немного улучшило мое использование памяти.
Теперь есть еще две большие операции выделения памяти:
И этот код, я думаю, принадлежит тому, что отображает 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
.
Спасибо.