Estoy sincronizando alnetworkingedor de 5000 imágenes desde el server en mi aplicación iPad. La cantidad de esas imágenes es de alnetworkingedor de 2.5 GB y mi iPad también tiene suficiente espacio.
Pero después de sincronizar solo 375 imágenes mi aplicación comienza a fallar con la siguiente razón
malloc: *** mmap(size=1048576) failed (error code=12) *** error: can't allocate region *** set a breakpoint in malloc_error_break to debug
2013-02-14 06:20:50.058 AAA[1250:907] ***
Terminating app due to uncaught exception 'NSMallocException', reason: 'Attempt to allocate 1048576 bytes for NS/CFData failed' *** First throw call stack:
Estoy guardando imágenes en el Directorio de documentos utilizando datos básicos.
Guíame si hay alguna restricción de save datos para la aplicación. Y toda esta operación que estoy realizando en hilo principal.
for (int i = 0; i < [shadowElement3 count]; i++) { NSMutableArray* array = [[NSMutableArray alloc] init]; Product* failedBankInfo = [NSEntityDescription insertNewObjectForEntityForName:@"Product" inManagedObjectContext:context]; NSXMLElement* element11 = [shadowElement3 objectAtIndex:i]; NSString* strPath = [element11 stringValueForNode:@"B1_COD"]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:strPath]; NSLog(@"%@",[element11 stringValueForNode:@"img"]); NSData* receivedData = [NSData dataWithContentsOfURL:[NSURL URLWithString: [element11 stringValueForNode:@"img"]]]; [receivedData writeToFile:savedImagePath atomically:YES]; [array addObject:savedImagePath];
}
Un par de cosas:
enumerateObjectsUsingBlock:
lugar de un for / loop. Vea aquí por qué. Prueba algo parecido a esto:
NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity:[shadowElement3 count]]; NSXMLElement* element11; NSString* strPath; NSString *savedImagePath; Product* failedBankInfo; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES); NSString *documentsDirectory = [paths objectAtIndex:0]; [context setUndoManager:nil]; for (int i = 0; i < [shadowElement3 count]; i++) { @autoreleasepool{ failedBankInfo = [NSEntityDescription insertNewObjectForEntityForName:@"Product" inManagedObjectContext:context]; element11 = [shadowElement3 objectAtIndex:i]; strPath = [element11 stringValueForNode:@"B1_COD"]; savedImagePath= [documentsDirectory stringByAppendingPathComponent:strPath]; NSData* receivedData = [NSData dataWithContentsOfURL:[NSURL URLWithString: [element11 stringValueForNode:@"img"]]]; [receivedData writeToFile:savedImagePath atomically:YES]; [array addObject:savedImagePath]; // you don't seem to be doing anything with the Managed Object you created, // I assume you are saving the path. So do so and batch save the context. // This will help free up memory. failedBankInfo.pathName = savedImagePath; if ( i % 100 ==0 ){ NSError *error; [context performBlock:^{ [context save:&error]; // handle error // reset the context cause you don't seem to be doing anything else // with the objects. This will free up memory [context reset]; }]; } } } // One last save NSError *error; [context performBlock:^{ [context save:&error]; // handle error is exercise for the reader. // reset the context cause you don't seem to be doing anything else // with the objects. This will free up memory [context reset]; }];
Buena suerte.
Es posible que deba usar un grupo de Autorelease. De acuerdo con el documento, "si escribe un bucle que crea muchos objects temporales".