0

I have created a view in which background is changing randomly.A total of 10 images .that i am using for displaying .

Below is the code for Background images.

- (void)viewWillAppear:(BOOL)animated
{
    myTimer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(changeImage) userInfo:nil repeats:YES];
}

-(void)changeImage
    {
        self.imgView.image=nil;
        int randNum = rand() % (9 - 1) + 1;.
        NSString *num = [NSString stringWithFormat:@"%d", randNum];
        self.imgView.image=[UIImage imageNamed:[NSString stringWithFormat:@"%@.png",num]];
    }

Code is working fine .

My question is;its showing over 34mb memory usage ,when i push other view it's still over 34 mb.although i have make the myTimer variable nil;

enter image description here

- (void)viewWillDisappear:(BOOL)animated
{
     [myTimer invalidate];
      self.imgView.image=nil;
      myTimer = Nil;
}

How can i manage memory usage here?

Shekhu
  • 1,998
  • 5
  • 23
  • 49
  • 3
    imageNamed: caches the image. this could be the cause of your issue. See http://stackoverflow.com/questions/924740/dispelling-the-uiimage-imagenamed-fud for more info. – CW0007007 Jul 23 '14 at 07:29
  • 1
    You also want to call the super implementation for `viewWillAppear` and `viewWillDisappear` – Oliver Atkinson Jul 23 '14 at 07:32

3 Answers3

1

You have to invalidate your timer, setting it to nil will not prevent it from firing:

Once scheduled on a run loop, the timer fires at the specified interval until it is invalidated. A non-repeating timer invalidates itself immediately after it fires. However, for a repeating timer, you must invalidate the timer object yourself by calling its invalidate method. Calling this method requests the removal of the timer from the current run loop; as a result, you should always call the invalidate method from the same thread on which the timer was installed. Invalidating the timer immediately disables it so that it no longer affects the run loop. The run loop then removes the timer (and the strong reference it had to the timer), either just before the invalidate method returns or at some later point. Once invalidated, timer objects cannot be reused.

So you need

[myTimer invalidate];
myTimer = nil;

To stop it running.

In terms of the memory use; what are you expecting to happen? If you've just pushed a new view on the navigation stack the old view is still around and its contents will be in memory. The layer cache won't be removed until the app comes under memory pressure, and 34MB probably isn't going to cause that.

As pointed out in comments, imageNamed caches images in memory (again, until you come under memory pressure) and you also need to call the super implementations of viewXXappear to make sure UIKit is handling things properly.

Try simulating a memory warning and seeing what happens. I don't think you've got anything to worry about, now you're invalidating the timer.

jrturton
  • 118,105
  • 32
  • 252
  • 268
  • did these changes too ;do check the updated question – Shekhu Jul 23 '14 at 07:33
  • .As if i load the view without the image it shows only 3 to 5 mb .but with images it show 10x memory usage. doing this ` self.imgView.image=nil;` seems reduce the memory by 5x but not to level view without the image.i am expecting is there any way arround to get it to 3 to 5 percentage,and BTW this is not for any project ,i am newbie in this and exploring it :) – Shekhu Jul 23 '14 at 10:03
  • You won't get the memory back completely unless the view is completely removed from memory and the cache is cleared. You're worrying about nothing. I don't understand what you mean by "3 to 5 percentage". – jrturton Jul 23 '14 at 10:56
0

Also try adding to viewdiddisappear,

self.imgView=nil;
NKB
  • 651
  • 5
  • 13
0

The method imageNamed: caches the image it only evict it during memory pressure situations, try to use imageWithContentsOfFile: and when you want to force a release set the image property of the image view to nil.

Andrea
  • 26,120
  • 10
  • 85
  • 131