Sto implementando un'app per iOS che deve recuperare una grande quantità di immagini su HTTP. Ho provato diversi approcci, ma indipendentemente da ciò che faccio, Instuments mostra costantemente l'aumento delle allocazioni di memoria e l'App si blocca prima o poi quando la eseguo su un dispositivo. Non ci sono perdite mostrate dagli strumenti.Allocazione di memoria in costante aumento durante il recupero di immagini su HTTP in iOS
Finora ho provato i seguenti approches:
- recuperano le immagini utilizzando un NSURLConnection sincrona all'interno di un NSOperation
- Fetch le immagini utilizzando un NSURLConnection asincrona in un NSOperation
- Fetch le immagini utilizzando [ NSData dataWithContentsOfURL: url] nella discussione principale
- Scarica le immagini utilizzando ASIHTTPRequest sincrono all'interno di una NSOperazione
- Scarica l'immagine immagini utilizzando ASIHTTPRequest asincrono e aggiungendolo a un NSOperationQueue
- Fetch le immagini utilizzando asincrona ASIHTTPRequest e utilizzando un completionBlock
L'albero delle chiamate in Instrumetns dimostra che la memoria si consuma durante l'elaborazione HTTP-risposta. In caso di NSURLConnection asincrono è in
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
}
nel caso del NSURLConnection sincrono, Instruments mostra un CFData (deposito) voce crescente. Il problema con ASIHTTPRequest sembra essere lo stesso con il NSURLConnection asincrono in una posizione di codice analoga. L'approccio [NSData dataWithContentsOfURL: url] mostra una quantità crescente di allocazione di memoria totale in questa affermazione.
Sto utilizzando un NSAutoReleasePool quando la richiesta viene eseguita in un thread separato e ho provato a liberare memoria con [[NSURLCache sharedURLCache] removeAllCachedResponses] - nessun successo.
Eventuali idee/suggerimenti per risolvere il problema? Grazie.
Modifica: Il comportamento si presenta solo se persisto le immagini utilizzando CoreData. Ecco il codice corro come un 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];
}
Tutti CoreData cose relative avviene nel Main-thread qui, quindi non ci dovrebbe essere alcun problema multithreading CoreData. Tuttavia, se persisto le immagini, Instruments mostra allocazioni di memoria costantemente crescenti nelle posizioni sopra descritte.
Edit II:
CoreData codice relativo:
-(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];
}
Da CoreDataHelper (self.managedObjectContext è scegliere il NSManagedObjectContext utilizzabile nel thread corrente):
-(NSManagedObject *) createObject:(NSString *) entityName {
return [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:self.managedObjectContext];
}
È possibile riprodurre il problema con un [piccolo esempio di codice] (http://sscce.org/) e postarlo? – zoul
Non potevo! Anche se Instruments mostra una memoria crescente nelle posizioni menzionate, il comportamento si mostra solo se memorizzo le immagini usando CoreData. – sink12
Hai trovato la ragione per la crescita costante della memoria? –