0

I have a part in my project, where I have to fill many arrays and dictionaries with custom classes. During the process the memory usage starts to increase of course. But at the end when I remove items from everywhere using removeAllObjects, the memory usage remains on the same level instead of decreasing to the starting value.

I made a simplified code which does not make sense of course but reproduces the original issue I am getting:

Header:

@interface ViewController : UIViewController

@property (strong, nonatomic) NSMutableArray *imageArray;
@property (strong, nonatomic) NSTimer *timer;

- (IBAction)start:(id)sender;
- (IBAction)stop:(id)sender;

@end

Implementation:

@implementation ViewController
....

- (IBAction)start:(id)sender
{
    [self.loadingIndicator startAnimating];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(addImages) userInfo:nil repeats:YES];
}

- (IBAction)stop:(id)sender
{
    [self.loadingIndicator stopAnimating];
    [self.timer invalidate];
    [self.imageArray removeAllObjects];
}

- (void)addImages
{
    int i = 0;

    while (i < 500)
    {
        UIImage *image = [UIImage imageNamed:@"test.png"];
        [self.imageArray addObject:image];
        i++;
    }
}
...
@end

Issue:

When I call start, after 1 min the memory usage increases from 3.9 MB to 58 MB. It is fine, but when I call stop, where removelAllObjects is called, it is still remains the same value, 58 MB.

What am I doing wrong? I am using ARC!

2
  • have you tried "trigger memory warning" in the simulator to see if the memory is only released when there is memory pressure? Or what happens when you reset the array by creating a new one, or just assigning nil to self.imageArray Commented Apr 3, 2015 at 17:12
  • I tried on Simulator now, and the weird thing is that it work perfectly, after removing all objects from the list the memory usage decreases to the original value without even triggering memory warning. So the question why is this behaviour different on real device? Btw, reset the array or setting to nil produces the same behaviour. Commented Apr 7, 2015 at 12:20

1 Answer 1

4

Images created with "imageNamed:" are cached, and if nobody else has a strong reference, then the operating system will release them when it feels it is a good idea to do it.

That avoids situations where you call imageNamed: repeatedly and each time a new image is created, which is rather expensive.

Sign up to request clarification or add additional context in comments.

2 Comments

I know you're right (upvoted it too) and not looking to dispute that at all, but I don't know if it completely explains what is going on here. Note that in this particular example the same file is loaded 500 times in a loop. it ought be cached on the first iteration through this loop, correct? So unless this file is huge I don't think this is the entire explanation. (Not that I have a better one..)
In the original environment I don't use images in the arrays, instad I use customer classes, so I don't think this is only about caching "imageNamed".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.