Mam aplikację opartą na ARC, która ładuje około 2000 dość dużych (1-4 MB) zakodowanych obrazów Base64 z usługi internetowej. Konwertuje ciągi dekodowane Base64 na pliki obrazów .png
i zapisuje je na dysku. Wszystko to odbywa się w pętli, w której nie powinienem mieć żadnych wzmianek źródłowych.Obiektywny C UIImagePNGReprezentacja pamięci operacyjnej (przy użyciu ARC)
Sprofilowałem swoją aplikację i okazało się, że UIImagePNGRepresentation zajmowało około 50% dostępnej pamięci.
Sposób, w jaki go widzę, UIImagePNGReprezentacja buforuje obrazy, które tworzy. Jednym ze sposobów rozwiązania tego problemu jest wyczyszczenie pamięci podręcznej. Wszelkie pomysły, jak można to zrobić?
Innym rozwiązaniem byłoby użycie czegoś innego niż UIImagePNGRepresentation?
Już wypróbowałem to bez powodzenia: Memory issue in using UIImagePNGRepresentation. Nie wspominając o tym, że nie mogę naprawdę skorzystać z dostarczonego tam rozwiązania, ponieważ spowolniłoby to moją aplikację.
Jest to metoda, którą wywołuję z mojej pętli. UIImage jest obraz konwertowany z 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: wymiary obrazu różnią się mniej więcej od 1000 do 3000 * 800 * 2000.
Próbowałem autoreleasepool, ale to nie pomogło. Z jakiegoś powodu aplikacja ulega awarii, gdy próbuję profilować ją z autoreleasepool. Dodam wymiary obrazu do mojego pytania. – JHollanti
Dodałem sprawę autoreleasepool do kilku innych miejsc i cała sprawa zaczęła działać. Byłoby o wiele łatwiej zacząć, gdybym mógł profilować moją aplikację, gdyby zawierał autoreleasepools. @vikingosegundo Miałeś kiedyś problem z profilowaniem, z którym się borykam? – JHollanti
nie. ale często mam problemy debuggera i profilowania z lldb. Wróciłem do gdb. – vikingosegundo