0

I have 5 animations on a view controller. This is already very memory intensive as they are retina quality.

THIS IS MY CODE

//Panel 1 Animation
    NSArray *panel1Frames = [NSArray array];
    panel1Frames = [[NSArray alloc] initWithObjects:
                 [UIImage imageNamed:@"origami_panel010001.png"],
                 [UIImage imageNamed:@"origami_panel010002.png"],
                 [UIImage imageNamed:@"origami_panel010004.png"],
                 [UIImage imageNamed:@"origami_panel010005.png"],
                 [UIImage imageNamed:@"origami_panel010006.png"],
                 [UIImage imageNamed:@"origami_panel010007.png"],
                 [UIImage imageNamed:@"origami_panel010008.png"],
                 [UIImage imageNamed:@"origami_panel010009.png"],
                 [UIImage imageNamed:@"origami_panel010010.png"],
                 [UIImage imageNamed:@"origami_panel010011.png"],
                 [UIImage imageNamed:@"origami_panel010012.png"],
                 [UIImage imageNamed:@"origami_panel010013.png"],
                 [UIImage imageNamed:@"origami_panel010014.png"],
                 [UIImage imageNamed:@"origami_panel010015.png"],
                 [UIImage imageNamed:@"origami_panel010016.png"],
                 [UIImage imageNamed:@"origami_panel010017.png"],
                 [UIImage imageNamed:@"origami_panel010018.png"],
                 [UIImage imageNamed:@"origami_panel010019.png"],
                 [UIImage imageNamed:@"origami_panel010020.png"],
                 [UIImage imageNamed:@"origami_panel010021.png"],
                 [UIImage imageNamed:@"origami_panel010022.png"],
                 [UIImage imageNamed:@"origami_panel010023.png"],
                 [UIImage imageNamed:@"origami_panel010024.png"],
                 [UIImage imageNamed:@"origami_panel010025.png"],
                 [UIImage imageNamed:@"origami_panel010026.png"],
                 [UIImage imageNamed:@"origami_panel010027.png"],
                 [UIImage imageNamed:@"origami_panel010028.png"],
                 [UIImage imageNamed:@"origami_panel010029.png"],
                 [UIImage imageNamed:@"origami_panel010030.png"],
                 [UIImage imageNamed:@"origami_panel010031.png"],
                 [UIImage imageNamed:@"origami_panel010032.png"],
                 [UIImage imageNamed:@"origami_panel010033.png"],
                 [UIImage imageNamed:@"origami_panel010034.png"],
                 [UIImage imageNamed:@"origami_panel010035.png"],
                 [UIImage imageNamed:@"origami_panel010036.png"],
                 [UIImage imageNamed:@"origami_panel010037.png"],
                 [UIImage imageNamed:@"origami_panel010038.png"],
                 [UIImage imageNamed:@"origami_panel010039.png"],
                 [UIImage imageNamed:@"origami_panel010040.png"],
                 [UIImage imageNamed:@"origami_panel010041.png"],
                 [UIImage imageNamed:@"origami_panel010042.png"],
                 [UIImage imageNamed:@"origami_panel010043.png"],
                 [UIImage imageNamed:@"origami_panel010044.png"],
                 [UIImage imageNamed:@"origami_panel010045.png"],
                 [UIImage imageNamed:@"origami_panel010046.png"],
                 [UIImage imageNamed:@"origami_panel010047.png"],
                 [UIImage imageNamed:@"origami_panel010048.png"],
                 [UIImage imageNamed:@"origami_panel010049.png"],
                 [UIImage imageNamed:@"origami_panel010050.png"],
                 [UIImage imageNamed:@"origami_panel010051.png"],
                 [UIImage imageNamed:@"origami_panel010052.png"],
                 [UIImage imageNamed:@"origami_panel010053.png"],
                 [UIImage imageNamed:@"origami_panel010054.png"],
                 [UIImage imageNamed:@"origami_panel010055.png"],
                 [UIImage imageNamed:@"origami_panel010056.png"],
                 [UIImage imageNamed:@"origami_panel010057.png"],
                 [UIImage imageNamed:@"origami_panel010058.png"],
                 [UIImage imageNamed:@"origami_panel010059.png"],
                 [UIImage imageNamed:@"origami_panel010060.png"],
                 [UIImage imageNamed:@"origami_panel010061.png"],
                 [UIImage imageNamed:@"origami_panel010062.png"],
                 [UIImage imageNamed:@"origami_panel010063.png"],
                 [UIImage imageNamed:@"origami_panel010064.png"],
                 [UIImage imageNamed:@"origami_panel010065.png"],
                 nil];
    panel1Image.animationImages = panel1Frames;
    panel1Image.animationDuration = 3.0;
    panel1Image.animationRepeatCount = 1;

This loads when a UIButton is pressed, is there anyway to load the images before hand?

Furthermore, Is there a way to make it so that only one animation can play at once? Would this reduce the amount of memory used?

Thanks!

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Rob Swish
  • 37
  • 8

1 Answers1

0

Your problem is that ios defers actual loading of the images until they need to be rendered. Instead of what you have, create an array of names, iterate over those, create an image as you do now, ask it for its CGImage, then use that to create another uiimage that you save in a mutable array. If this works for you add a comment, there is a subtlety with scale.

You could put the uiimages in a NSCache if you are worried about total memory.

If you want to only have one animation play then set enabled to off on other buttons while one is playing.

EDIT: if you really cannot get over the memory hurtle, create a demo project with one animation per button press and post it to a public site, then update your original question with a reference to the project.

David H
  • 40,852
  • 12
  • 92
  • 138
  • The biggest problem seems to be the total memory, I updated the final panel of images to be retina and now it crashes every time, how can i put them in a NSCache? This may be all I need. Thanks. – Rob Swish Dec 15 '13 at 15:57
  • Read up on NSCache - its like a NSSet but the system can delete objects, so when you go to get an image it may be gone (then you have to read it back from the file system). Also, I see all your images are pngs - these are often much larger than jogs. I'd suggest changing a few and see what the size difference is. You might be able to do your own animation using a CADisplay loop, and updating your own image view. This way you could simply keep a few images ahead of why you need to display. None of this is simple - you want large image animations you need to do the work. Maybe make a movie? – David H Dec 15 '13 at 17:05
  • I tried the whole movie route and it just seemed to clunky, not as streamlined. The animation route is working so well for me. I have literally every bit of functionality I need done. It's just this issue with memory now. By jogs do you mean jpgs? ha :) I will try this also! Is there a link or a resource you could recommend so I could read up on NSCache? I am relatively new to Xcode. I appreciate your interest in my question! I think with your help I can crack this. Thanks. – Rob Swish Dec 15 '13 at 19:02
  • Hmm - spell correct changed it on me. Yes jpeg. NSCache usage is an advanced topic. If you convert your pngs to jpegs in Preview on the Mac, you can spec a really low "quality", get great compression, and the perceived difference is quite small. Also, with some time effort (or a good tool like Screeny, you can make a movie with transitions at exact intervals just like a animation would, but since each image is close to the preceding ones you can get lots of compression "for free". YMMV – David H Dec 15 '13 at 19:08
  • I would have to have 5 individual movies, as I'd like this user to be able to replay each part individually. Movies I got a fair way with but since using animations, the only thing I haven't been able to do is sort this memory issue, I have all the other functionality I wanted (Just about still sound issue to fix), I will try the jpg, and I will read up on the NSCache. – Rob Swish Dec 15 '13 at 20:42
  • Well, read in one movie / photo set at a time, when the user starts one delete the last one. Just don't keep everything around. A related answer: http://stackoverflow.com/a/16340035/1633251 BTW you indicated memory concerns - 18M unlikely a problem – David H Dec 15 '13 at 20:46
  • The total of all of the images used as png = a file size of 16.826 mb! So... surely the size of these images isn't such a big deal, with this knowledge, and knowing I want to use animation, is NSCache the best way to go? – Rob Swish Dec 15 '13 at 20:47
  • So if my image size being 16.826mb is unlikely to be a problem, how come Xcode is displaying that the iPad is using put 450mb memory to run it? Thanks again for the answer, starting one and deleting the last sounds like what I need to do, I will read into this now, thanks for the link. – Rob Swish Dec 15 '13 at 21:47
  • BTW, check out www.tinypng.com - its possible you can get great compression using their tools. iOS can read PNGs much easier than JPGs, so this may also be a way to get the file sizes down. – David H Dec 18 '13 at 15:43
  • Thank you for your continued concern. – Rob Swish Dec 19 '13 at 01:14
  • Could it be due to memory leaks? When I analyse my app it has 2 memory leaks, however, some they are both within Apples page based application template. What do you think? – Rob Swish Dec 19 '13 at 03:26
  • When I launch my app, it plays a background sound and loads a simple view controller with one UIImage view on it. Yet my memory is at 67.9mb, surely thats not right ? – Rob Swish Dec 19 '13 at 03:27
  • OK I just did a nice fresh app from the start, with no memory leaks, and it starts and loads with a lot less memory being used, but I didn't have a background sound. When I play the animations the memory soon hits the top and then sometimes crashes. Got to get this image cache thing working then I think. – Rob Swish Dec 19 '13 at 03:45
  • So your going in the proper direction. Make a third new app it only plays animations at say a button press. Get that working. Use instruments to watch memory and fix any leaks. – David H Dec 19 '13 at 15:12
  • David it turns out all of my memory is going to the images once the array has loaded them. How can I tell it to unload these arrays after they have played? Or should I still look into NSCache? – Rob Swish Dec 21 '13 at 04:00
  • Do not use image named, it's suppose to cache them. Use the image from file instead - read the UIImage class ref for specifics. – David H Dec 21 '13 at 05:11
  • Crashing due to using all memory with images is a well know problem, a working solution is here: https://stackoverflow.com/questions/442076/method-for-animating-images-like-a-movie-on-iphone-without-using-mpmovieplayer#answer-6077394 – MoDJ Mar 20 '15 at 20:42