Search code examples
iosmemory-managementuiimageviewuiimage

Loading a lot of remote images - memory problems


first of all, I am not using ARC as I had even bigger problems with it and I need full control of my memory management.

Here is the situation: I need to load a lot of remote JPEG images from a server and display them in a scrollview. The top images in the scroll view get released once the user scrolls down a bit. That is working, the containing views are all released normally. Problem is, that after loading the remote image, a lot of memory stays allocated and doesn't get released. Here is my code to fetch the remote images(subclassing UIImageView):

- (void)downloadImage    {
    NSData *posterData = [[NSData alloc] initWithContentsOfURL:self.url options:NSDataReadingUncached error:nil];
    UIImage *img = [[UIImage alloc] initWithData:posterData];
    [posterData release];
    self.image = img;
    [img release];
}
// that gets called from:
- (void)setImageFromURL:(NSURL *)_url{
    [NSThread detachNewThreadSelector:@selector(downloadAndLoadImage) toTarget:self withObject:nil];
}

When I inspect my code with Instruments, my UIImageView gets released as intended, but the following still stucks in my memory and spams it: Instruments

Apparently CFData, Malloc 9.00 KB, NSConcreteData are all resulting from my downloadImage method. What am I doing wrong? This is driving me crazy...how do you load a lot of remote images memory safe? I also tried NSURLConnection, but it was rather worse then better. :(

Image size varies from 6 to 25KB.

Many thanks in advance!

UPDATE

I ended up using SDWebImage which works great and is very easy to use.


Solution

  • Is image downloading on a background thread? If yes then where is NSAutoreleasePool? You have to add:

    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    
    // your downloading thread code here
    
    [pool release];
    

    Or for ARC:

    @autoreleasepool {

        // your downloading thread code here
    

    }

    Also if image download happens on a background thread you cannot do self.image = img; you should call it on the main thread, because UI elements should be modified only from the main thread:

    [self performSelectorOnMainThread:@selector(setImage:) withObject:img waitUntilDone:YES];
    

    Actually SDWebImage library does everything for you, and has memcache and disk cache