0

I m loading lots of rather large images in my viewcontroller, using

NSUInteger nimages = 0;

for (; ; nimages++) {

    NSString *nameOfImage_ = @"someName";

    NSString *imageName = [NSString stringWithFormat:@"%@%d.jpg", nameOfImage_, (nimages + 1)];

    image = [UIImage imageNamed:imageName];
    if (image == nil) {
        break;
    }

    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];

    //some other stuff....

    [imageView release];
}

the usual unloading occurs in - (void)viewDidUnload and - (void)dealloc with self.image = nil; and [image release];

It seems after a few "loading" and "unloading" the cache still grows to the point of no return!! :)

and the app crashes...

any ideas??? how do i empty my cache? and where?

thanks

EDIT:

ok this is what i was doing wrong. Apparently this piece of code fixes the whole caching problem:

image = [[UIImage imageNamed:imageName] autorelease];

with autorelease being the key here.

thanks for the replies...

George Asda
  • 2,119
  • 2
  • 28
  • 54
  • Are dealloc and viewDidUnload actually called? Put some NSLog in those methods to make sure. And how do you create your view? You seem to have some problems with memory management, so probably your view sticks around longer than you think. And this view holds the imageViews which all have a reference to an image. That's why they are never released. – Matthias Bauch May 22 '12 at 15:58
  • yes the view does sticks around. I have tried viewDidDissapear to release, removefromsuperview, = nil but still get the memory warning and eventually crash. – George Asda May 22 '12 at 19:16

5 Answers5

4

Thank you all for your suggestions.

Solution:
Used ARC and imageWithContentsOffFile to initialize the Images.

image = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:imageName ofType:nil]];

And Yes, imageNamed is only good for... well for nothing big...

Haresh Chaudhary
  • 4,390
  • 1
  • 34
  • 57
George Asda
  • 2,119
  • 2
  • 28
  • 54
  • Hi, i have the same problem and i did what you said, but it's now laggy and crashes faster (just like you said in comments below one answer). is there anything additional that made a solution work for you? I read that `imageWithContentsOfFile` doesn't cache images and it's exactly what i'm looking for, so have you got any tips for me? – cyborg86pl Jul 04 '13 at 16:45
  • Yes. Use imageWithContentsOfFile. That did the trick for me back then. I have since abandoned the whole loading of images in my project, so not able to help you further. – George Asda Jul 06 '13 at 22:07
  • [UIImage imageNamed] should really only be used for small UI elements. – jjxtra Dec 17 '13 at 21:41
3
image = [[UIImage imageNamed:imageName] autorelease];

This is incorrect. In keeping with the memory management rules, you shouldn't be releasing (or autoreleasing) the image because you didn't allocate or retain it. "imageNamed" doesn't contain "alloc", "new", "copy", or "retain".

As some of the other answers explain, you should load your images with a different method if you want more control over the memory they use.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • In my h. header i do this: @property (nonatomic, retain) UIImage *image; so i guess it is ok to autorelease it. Am i wrong here? – George Asda May 22 '12 at 22:12
  • 1
    Yes, you are wrong. What happens if the cache decides to release the image? You've now got a pointer to a nonexistent object. Or, if you set your `image` property to nil, you'll cause the image to be released and UIImage's cache will have a bad pointer. **Do this:** drop the `autorelease` from your code. When you're done with the image, set your `image` property to nil. That's all you're responsible for. **Even better:** switch to ARC and let the compiler handle the memory management. – Caleb May 22 '12 at 22:18
  • ARC still crashes my app. Although it takes longer to do so. i ll try nil-ing the image... – George Asda May 22 '12 at 22:32
  • nil-ing when done with the image gave me three times the life span of the app compared to what i had before. (I didnt get any mem warnings this time) but then... guess what?? it crashed again... if two consecutive viewers (or the same viewer) containing the same series of images are loaded/ selected then the app crashes, cause images have been previously nil-ed??? is that correct? how do i fix this then? – George Asda May 23 '12 at 07:28
1

imageNamed is an awful way to load images in reality, it never releases loaded images unless forced and keeps them in the cache forever. You should implement your own, more intelligent cache. A simple NSMutableDictionary gives the same functionality but with more flexibility.

For a more in-depth discussion you can read this: http://www.alexcurylo.com/blog/2009/01/13/imagenamed-is-evil/

Hampus Nilsson
  • 6,692
  • 1
  • 25
  • 29
  • 1
    really? that FUD is still circling around? That bug that caused `imageNamed:` to never empty its cache was fixed like 3 years ago. Maybe it's time to update your bookmarks. http://stackoverflow.com/questions/924740/dispelling-the-uiimage-imagenamed-fud – Matthias Bauch May 22 '12 at 16:10
0

Use another method to initialize you image. imageNamed caches.

dasdom
  • 13,975
  • 2
  • 47
  • 58
0

Instead of using using imageNamed you can use imageWithContentsOfFile: Or check this article

link 0

link 1

Community
  • 1
  • 1
Moonkid
  • 881
  • 7
  • 17
  • I did but image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageName ofType:nil]]; crashes faster than previously!! – George Asda May 22 '12 at 15:33
  • Also tried using ARC. it seems to be working at first, but then again it crashes! – George Asda May 22 '12 at 15:38