iphonememory-managementcrashimagenamed

iPhone App crashes after switching, possibly due to UIImage imageNamed


My app moves 10 UIImageViews randomly around the screen, and once an UIImageView hits the corner, it changes its image. The problem is: after switching between apps and going back to mine, the app crashes.

The console gives me this message:

"App" exited abnormally with signal 10: Bus error

The crash log states this:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)

Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000000000011

Crashed Thread:  0  Dispatch queue: com.apple.main-thread

I think the problem is due to the fact that I'm using UIImage imageNamed, here is the code:

In ViewController.h:

UIImage *red;
UIImage *green;
UIImage *blue;

UIImageView *ballOne;
UIImageView *ballTwo;
UIImageView *ballThree;
UIImageView *ballFour;
// And declare UIImageView for other balls
int clr

In ViewController.m:

- (void)viewDidLoad {
  ...
  red = [UIImage imageNamed: @"redTexture.png"];
  green = [UIImage imageNamed: @"greenTexture.png"];
  blue = [UIImage imageNamed: @"blueTexture.png"];
  ...
}
- (void)moveAll:(NSTimer *)theTimer{
  ...
  // If UIImageView touches a corner, Do this:
  clr = arc4random()%3 + 1;
  switch (clr) {
    case 1:
     [ballOne setImage:red];
     break;
    case 2:
     [ballOne setImage:green];
     break;
    case 3:
     [ballOne setImage:blue];
     break;
    default:
     break;
   }
   // And do this for the rest of 9 "balls" 
}

Why does my App crash, and how do I solve it?


Solution

  • [UIImage imageNamed:] returns an autoreleased instance of a UIImage. That means that the memory will be released as soon as the event loop ends.

    Yo need to retain those instance either by calling.

    [[UIImage imageNamed:@"blabl.png"] retain]
    

    or (preferred method) by setting up your blue, red, green members as property with

    @property(nonatomic, retain) UIImage* red;
    

    and your code will be like :

    - (void)viewDidLoad {
      ...
      self.red = [UIImage imageNamed: @"redTexture.png"];
      self.green = [UIImage imageNamed: @"greenTexture.png"];
      self.blue = [UIImage imageNamed: @"blueTexture.png"];
      ...
    }
    

    Of course do not forget to release them when your done otherwize you will have the opposite of what you have now : memory leaks.

    to release red, call

    [red release]
    

    inthe dealloc method.