Problem with iOS memory (ARC) when loading and saving a large number of images from the server

The following code downloads more than 700 images from a server with different sizes, so the problem is that the memory (even with ARC) is never released, and at the end there is a warning about saving memory, followed by the application exit. I tried @autoreleasepool in this method and didn't seem to work. In addition, I tried to stop the for loop in different places to find out if the memory was released after it was completed, but it is not.

This method is called inside the for loop and gets the image URL and short name. It was tested in the background thread and the main thread with the same results (reasonable memory).

-(void)saveImage:(NSString*)image name:(NSString*)imageName{ int k = 0; for (int j = 0; j < [imageName length]; j++) { if ([imageName characterAtIndex:j] == '/') { k = j; } }if (k != 0) { imageName = [imageName substringFromIndex:k+1]; } NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", imageName]]; if ([fileManager fileExistsAtPath:fullPath]) { [fileManager removeItemAtPath:fullPath error:nil]; } NSURL *url = [NSURL URLWithString:image]; NSData *data = [[NSData alloc]initWithContentsOfURL:url]; NSLog(@"Saved: %d:%@", [fileManager createFileAtPath:fullPath contents:data attributes:nil], url); data = nil; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { int cacheSizeMemory = 4*1024*1024; // 4MB int cacheSizeDisk = 32*1024*1024; // 32MB NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"]; [NSURLCache setSharedURLCache:sharedCache]; self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]; self.window.rootViewController = self.viewController; [[UIApplication sharedApplication] setStatusBarHidden:YES]; [self.window makeKeyAndVisible]; return YES; } - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { NSLog(@"mem warning, clearing cache"); [[NSURLCache sharedURLCache] removeAllCachedResponses]; } 

Allocations

+4
source share
2 answers

Based on the screenshot, I think the problem is with NSURL caching, not NSData objects. Can you try the following:

In your application deletion, set the source URL cache:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Do initial setup int cacheSizeMemory = 16*1024*1024; // 16MB int cacheSizeDisk = 32*1024*1024; // 32MB NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"]; [NSURLCache setSharedURLCache:sharedCache]; // Finish the rest of your didFinishLaunchingWithOptions and head into the app proper } 

Add the following to your application delegate:

 - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { [[NSURLCache sharedURLCache] removeAllCachedResponses]; } 

A cache file will be created: "Library/Caches/your_app_id/nsurlcache"

A link to an Apple example is here: Cache URL

The code is not verified, but this (or something similar) should sort your problem + plus you can experiment with cache sizes.

Can you post another screenshot of Allocations in action with this code? I would expect the memory usage to stop growing and smooth out.

+5
source

" dataWithContentsOfURL " returns an NSData object with auto-implementation and which is usually not freed until the end of the execution loop or the end of the method , so it is not surprising that you quickly fill up the memory.

Change it to the explicit method " initWithContentsOfURL " and then force-release by executing " data = nil; " when you absolutely executed the image data.

+1
source

All Articles