1
votes

I am changing the image in UIImageView based on accelerometer input. The images are stored in an array. The application runs fine for a while and then crashes.

warning: check_safe_call: could not restore current frame

  1. I am not using "UIImage ImageNamed" method when populating the array.
  2. The total size of all images is around 12 Mb. But individual images are very light (<100 kb) and i am using only one image at a time from the array.
  3. Just in case there are any autoreleases, I have allocated a NSAutoreleasePool in view did load and am draining it in the didReceiveMemoryWarning method (which does get called 2, 3 times before the app crashes?).

Following is the code that creates images array:

    //create autorelease pool as we are creating many autoreleased objects
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSMutableArray *finalarr = [[NSMutableArray alloc] initWithCapacity:9];

NSLog(@"start loading");
for(int y = 0; y < 100; y+=10)
{
    NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:10];
    for(int x = 0; x < 10; x++)
    {
        NSString *imageName = [[NSString alloc] initWithFormat:@"0%d",y + x];

        UIImage *img = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageName ofType:@"png"]];
        [arr addObject:img];

        [imageName release];
        [img release];
    }
    [finalarr addObject:arr];
    [arr release];

}

NSLog(@"done loading");
// Override point for customization after app launch
viewController.imagesArray = finalarr;
[finalarr release];
//retain the array of images
[viewController.imagesArray retain];

//release the aurtorelease pool to free memory taken up by objects enqued for release
[pool release];

As the app runs smoothly for a while, which means array creation is definitely not the problem.

After this the following method is called from [accelerometer didAccelerate]

-(BOOL)setImageForX:(int)x andY:(int)y
{
[self.imageView setImage:(UIImage*)[(NSArray*)[self.imagesArray objectAtIndex:y] objectAtIndex:x]];
return TRUE;
}

So the only code being executed is the "UIImageView setImage". But no objects are being created here.

Please let me know if the code seems to have any leaks or i am doing something wrong.

Thanks,
Swapnil

1

1 Answers

2
votes

NSAutoreleasePool should be allocated and released in the same method. Allocating it in one place and releasing it in another is usually very bad (the example code you pasted uses it correctly however)

Loading images into memory will decompress them; a 100KB compressed PNG could easily be 2MB uncompressed.

You also seem to have an extra retain call that shouldn't be there: [viewController.imagesArray retain]; (I assume the imagesArray property is marked copy or retain and not assign)