Ho un'app basata su ARC che carica circa 2.000 immagini codificate Base64 di dimensioni abbastanza grandi (1-4MB) da un webservice. Converte le stringhe decodificate Base64 nei file immagine .png
e li salva sul disco. Questo è tutto fatto in un ciclo in cui non dovrei avere riferimenti persistenti.Problema di memoria Objective C UIImagePNGRresentation (usando ARC)
Ho profilato la mia app e ho scoperto che UIImagePNGR rappresentava circa il 50% della memoria disponibile.
Il modo in cui lo vedo, UIImagePNGRepresentation sta memorizzando nella cache le immagini che crea. Un modo per risolvere il problema sarebbe quello di svuotare quella cache. Qualche idea su come si potrebbe fare?
Un'altra soluzione sarebbe utilizzare qualcosa di diverso da UIImagePNGRepresentation?
Ho già provato questo senza fortuna: Memory issue in using UIImagePNGRepresentation. Per non parlare del fatto che non posso davvero usare la soluzione fornita lì perché renderebbe la mia app troppo lenta.
Questo è il metodo che chiamo dal mio ciclo. UIImage è l'immagine convertita da Base64:
+ (void)saveImage:(UIImage*)image:(NSString*)imageName:(NSString*)directory {
NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
NSString *pathToFolder = [documentsDirectory stringByAppendingPathComponent:directory];
if (![fileManager fileExistsAtPath:pathToFolder]) {
if(![fileManager createDirectoryAtPath:pathToFolder withIntermediateDirectories:YES attributes:nil error:NULL]) {
// Error handling removed for brevity
}
}
NSString *fullPath = [pathToFolder stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", imageName]]; //add our image to the path
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the path (image)
// clear memory (this did nothing to improve memory management)
imageData = nil;
fileManager = nil;
}
EDIT: dimensioni immagine variano approssimativamente da 1000 * 800-3000 * 2000.
Ho provato l'autorespiratore ma non è stato d'aiuto. Per qualche motivo l'app si arresta in modo anomalo quando provo a configurarlo con l'autoreleasepool. Aggiungo le dimensioni dell'immagine alla mia domanda. – JHollanti
Ho aggiunto il gioco di ruolo autoreleasepool ad un sacco di altri posti e l'intera cosa ha iniziato a funzionare. Sarebbe stato molto più facile iniziare se avessi potuto profilare la mia app quando conteneva autoreleasepools. @vikingosegundo Mai avuto questo problema di profilazione che sto affrontando? – JHollanti
no. ma ho spesso problemi di debugger e di profilazione con lldb. Sono tornato a gdb. – vikingosegundo