Я реализую приложение для iOS, которому нужно получать огромное количество изображений по HTTP.Я попробовал несколько подходов, но независимо от того, что я делаю, Instuments показывает постоянно увеличивающееся распределение памяти, и приложение рано или поздно падает, когда я запускаю его на устройстве.Приборы не показывают утечек.
До сих пор я пробовал следующие варианты:
- Извлечение изображений с использованием синхронного NSURLConnection в NSOperation
- Извлечениеизображения с использованием асинхронного NSURLConnection в NSOperation
- Извлечение изображений с помощью [NSData dataWithContentsOfURL: url] в главном потоке
- Извлечение изображений с использованием синхронного ASIHTTPRequest в рамках NSOperation
- Извлечение изображений с использованием асинхронного ASIHTTPRequest и добавление его в NSOperationQueue
- Извлечение изображений с использованием асинхронного ASIHTTPRequest и использование завершениеBlock
Дерево вызовов в Instrumetns показывает, что память используется во время обработкиHTTP-ответ.В случае асинхронного NSURLConnection это находится в
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
}
В случае синхронного NSURLConnection Instruments показывает растущую запись CFData (хранилище).Проблема с ASIHTTPRequest кажется такой же, как и с асинхронным NSURLConnection в аналогичной позиции кода.Подход [NSData dataWithContentsOfURL: url] показывает увеличение общего объема выделяемой памяти именно в этом операторе.
Я использую NSAutoReleasePool, когда запрос выполняется в отдельном потоке, и я попытался освободить память с помощью[[NSURLCache sharedURLCache] removeAllCachedResponses] - безуспешно.
Есть идеи / советы по решению проблемы?Спасибо.
Редактировать: Поведение отображается только при сохранении изображений с использованием CoreData.Вот код, который я запускаю как NSInvocationOperation:
-(void) _fetchAndSave:(NSString*) imageId {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *url = [NSString stringWithFormat:@"%@%@", kImageUrl, imageId];
HTTPResponse *response = [SimpleHTTPClient GET:url headerOrNil:nil];
NSData *data = [response payload];
if(data && [data length] > 0) {
UIImage *thumbnailImage = [UIImage imageWithData:data];
NSData *thumbnailData = UIImageJPEGRepresentation([thumbnailImage scaleToSize:CGSizeMake(55, 53)], 0.5); // UIImagePNGRepresentation(thumbnail);
[self performSelectorOnMainThread:@selector(_save:) withObject:[NSArray arrayWithObjects:imageId, data, thumbnailData, nil] waitUntilDone:NO];
}
[pool release];
}
Все связанные с CoreData вещи выполняются в основном потоке, поэтому не должно быть никаких проблем многопоточности CoreData.Однако, если я сохраню изображения, Instruments показывает постоянно увеличивающиеся выделения памяти в позициях, описанных выше.
Редактировать II:
Код, связанный с CoreData:
-(void) _save:(NSArray*)args {
NSString *imageId = [args objectAtIndex:0];
NSData *data = [args objectAtIndex:1];
NSData *thumbnailData = [args objectAtIndex:2];
Image *image = (Image*)[[CoreDataHelper sharedSingleton] createObject:@Image];
image.timestamp = [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]];
image.data = data;
Thumbnail *thumbnail = (Thumbnail*)[[CoreDataHelper sharedSingleton] createObject:@"Thumbnail"];
thumbnail.data = thumbnailData;
thumbnail.timestamp = image.timestamp;
[[CoreDataHelper sharedSingleton] save];
}
Из CoreDataHelper (self.managedObjectContext выбирает NSManagedObjectContext, используемый в текущем потоке):
-(NSManagedObject *) createObject:(NSString *) entityName {
return [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:self.managedObjectContext];
}