0

I will like to know how to release the memory from the animating array, somehow in instruments the animating picture are eating up 24MB of real memory. what should i do to release the memory ? the total picture file size are about 3MB in Mac OS.

*EDIT:*Cool, i enabled the ARC setting in the build setting, no longer crashing...but memory usages still hovering around 80 - 120mb physical memory.....

this is the line that run for the image.

    -(void)defaultSetup
{

    self.imageArray = [[NSMutableArray alloc] initWithObjects:
                       [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"default/d7.jpg"]],
                        [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"default/d9.jpg"]],
                        [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"default/d11.jpg"]],
                        [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"default/d27.jpg"]],
                        [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"default/d6.jpg"]],                        
                        nil];
    self.defaultID = [[NSMutableArray alloc] initWithObjects:@"0",@"1",@"2",@"3",@"0",nil];
    self.defaultImageCaption = [[NSMutableArray alloc] initWithObjects:@"Ver",@"Green",@"Red",@"Cru",@"East",nil];      


    NSUInteger count = [self.defaultID count];
    NSLog(@"Count %i",[self.defaultID count]);
    NSMutableArray *randomImgName = self.imageArray;
    NSMutableArray *randomID = self.defaultID;
    NSMutableArray *randomName = self.defaultImageCaption;

    for (NSUInteger i = 0; i < count; ++i) {
        // Select a random element between i and end of array to swap with.
        int nElements = count - i;
        int n = (arc4random() % nElements) + i;
        [randomName exchangeObjectAtIndex:i withObjectAtIndex:n];
        [randomImgName exchangeObjectAtIndex:i withObjectAtIndex:n];
        [randomID exchangeObjectAtIndex:i withObjectAtIndex:n];
    }
    self.imageArray = randomImgName;
    self.defaultID=randomID;
    self.defaultImageCaption=randomName;

    NSLog(@"default filename %@",self.defaultImageCaption);
    NSLog(@"default ID %@",self.defaultID);
    self.imageViewTop.alpha = 1.0;
    self.imageViewBottom.alpha = 0.0;
    self.imageViewBottom = [[[UIImageView alloc] initWithFrame:CGRectMake(0,44,320,367)] autorelease];
    self.imageViewTop = [[[UIImageView alloc] initWithFrame:CGRectMake(0,44,320,367)] autorelease];
    [self.view addSubview:imageViewTop];
    [self.view addSubview:imageViewBottom];

    self.buttonCaption = [UIButton buttonWithType:UIButtonTypeCustom];
    //default placement
    self.buttonCaption.frame = CGRectMake(245, 365, 70, 30);
    //[buttonCaption setTitle:@"\u00A9"  forState:UIControlStateNormal];
    [self.buttonCaption addTarget:self action:@selector(buttonCheck) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.buttonCaption];

    [self nextAnimation:buttonCaption.frame.size.width]; 

}

-(void)nextAnimation:(float)previousWidth {

    //picture loop
    imageViewTop.image = imageViewBottom.image;
    imageViewBottom.image = [imageArray objectAtIndex:[imageArray count] - 1];

    [imageArray insertObject:imageViewBottom.image atIndex:0];
    [imageArray removeLastObject];
    imageViewTop.alpha = 1.0;
    imageViewBottom.alpha = 0.0;

    //Name Caption
    NSString * tempCaption = [defaultImageCaption objectAtIndex:[defaultImageCaption count]-1];
    self.dID = [defaultID objectAtIndex:[defaultID count]-1];

    // make the buttons content appear in the top-left
    [buttonCaption setContentHorizontalAlignment:UIControlContentHorizontalAlignmentCenter];
    [buttonCaption setContentVerticalAlignment: UIControlContentVerticalAlignmentCenter ];



    [defaultImageCaption insertObject:tempCaption atIndex:0];
    [defaultImageCaption removeLastObject];
    [defaultID insertObject:dID atIndex:0];
    [defaultID removeLastObject];

    [UIView animateWithDuration:1 delay:2 options:0       
                     animations:^{                          
                         [buttonCaption setTitle:tempCaption  forState:UIControlStateNormal];
                         //NSLog(@"Name %@",tempCaption );
                         //NSLog(@"ID %@",dID);
                     } 
                     completion:^(BOOL  completed)
     {
     }];  
Trott
  • 66,479
  • 23
  • 173
  • 212
Desmond
  • 5,001
  • 14
  • 56
  • 115
  • Do you have ARC (automatic reference counting) enabled in this project btw? I assume not, since you're doing memory management stuff (autorelease etc.) yourself. – occulus Dec 03 '11 at 17:21

3 Answers3

1

When something is created with alloc and init or an initWith* (as is done here with imageArray) you can release it with release:

[self.imageArray release];

If there's autorelease or retain calls involved, things can get a little bit more tricky. But they don't seem to come into play here.

Trott
  • 66,479
  • 23
  • 173
  • 212
  • thanks for the quick reply Trott. the memory still the same in instrument, i added in the animation code, where should i releasing the image array ? – Desmond Dec 03 '11 at 17:25
1

Read up on Cocoa memory management. (I'm assuming you're not using ARC (automatic reference counting).) Btw, I'd consider using ARC, it makes your life easier. (It's a compile-time technology, so is backwards compatible with older iOS runtimes, but you don't get weak reference support on older iOS runtimes.)

To summarise the memory management rules: everything that increases your retain count on an object should be balanced by something that decreases the retain count at some point.

Things that increment the retain count:

self.propertyName = anInstance, when that property is declared with retain property.

[objectInstance retain].

[Class alloc], [Class new], [objectInstance copy] or variants beginning with copy.

Adding an object to a standard collection class (e.g. NSArray).

Things that decrement the retain count:

self.propertyName = <some other object instance or nil>, when that property is declared with retain property.

[objectInstance release]

[objectInstance autorelease] (causes a release at some later time).

Removing an object from a standard collection class (e.g. NSArray).

occulus
  • 16,959
  • 6
  • 53
  • 76
  • HI Occulus, i converted all my file to ARC with reflector except API i used.... still the the memory usage are still very high...really not sure why. – Desmond Dec 04 '11 at 11:20
0

If you load the images lazily (rather than getting array of UIImages imageArray make array of their locations) you can save lot of memory, and can easily clean up UIImage instances. By doing this, the max images loaded in memory would not be more than 3; it can save RAM.

example as requested:

while initializing the array,

self.imageArray = [[NSMutableArray alloc] initWithObjects:
               @"default/d7.jpg",
               @"default/d9.jpg",
               @"default/d11.jpg",
               @"default/d27.jpg",
               @"default/d6.jpg",                        
               nil];

while loading actual image

NSString* imgPath = [imageArray objectAtIndex:[imageArray count] - 1];
imgPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:imgPath];
imageViewBottom.image = [UIImage imageWithContentsOfFile:imgPath];

Let me know if it helps!

Prashant Rane
  • 436
  • 4
  • 11
  • You can find a link to a my PNG animator class here http://stackoverflow.com/questions/1008997/iphone-sdk-long-animations-with-animationimages-problem/3090167#3090167 – MoDJ Jun 21 '13 at 04:56