Problem changing image property of UIImageView

Discussion in 'iOS Programming' started by StevenMiles, May 24, 2009.

  1. StevenMiles macrumors newbie

    Joined:
    May 24, 2009
    #1
    Hi,

    I'm rather new to iPhone programming, and I can't get this figured out, in what should be a simple test program.

    I have a main view that contains two buttons and a UIImageView. On viewDidLoad, I load into the UIImageView the first of six images that are in my resource folder:

    Code:
    - (void)viewDidLoad {
    	self.imgNamesArray = [NSArray arrayWithObjects:@"Sima_bouncy", @"DannySpikes", @"DanSima", @"DaddyDanny", @"MikeHorse", @"SashaTeeth", nil];
    	NSString *strFirstImage = [[imgNamesArray objectAtIndex:0] stringByAppendingFormat:@".png"];
    	UIImage *img = [UIImage imageNamed:strFirstImage];
    	if (img != nil) {
    		[imgShown setImage:img];
    		[img release];
    	}
    	[strFirstImage release];
    	[super viewDidLoad];
    	}
    This works fine.

    imgShown is defined here:
    IBOutlet UIImageView *imgShown;
    and it is connected to the UIImageView on the screen that I placed using Interface Builder.

    If I click the "Load Next Image" button, the following code executes, and I am able to successfully cycle through the images on the iPhone's screen:

    Code:
    -(IBAction)loadNextImage:(id)sender {
    	currentImage++;
    	NSString *strNextImage = [[self.imgNamesArray objectAtIndex:currentImage] stringByAppendingFormat:@".png"];
    	UIImage *img = [UIImage imageNamed:strNextImage];
    	if (img != nil) {
    		[imgShown setImage:img];
    		[img release];
    	}
    	[strNextImage release];
    }
    However, I have another button, called "Load Previous Image," and the method loadPreviousImage is **identical** to loadNextImage above, except for the first line, which says
    currentImage--;
    a decrement instead of an increment. loadPreviousImage *never* works, it crashes the program.
    The debug window says:
    Program received signal: “EXC_BAD_ACCESS”.
    and it seems the crash happens on the following line:
    [imgShown setImage:img];


    More information:
    When I added the following line to the beginning of loadNextImage:
    currentImage++
    if (currentImage == 6) currentImage = 0;
    I expected to be able to cycle through the images, going back to the first after seeing the last when pressing "Load Next Image", but I get the same crash and error when it tries to load image index 0 again.

    Also, if loadNextImage ignores the currentImage integer and just says:
    NSString *strNextImage = [[self.imgNamesArray objectAtIndex:4] stringByAppendingFormat:mad:".png"];

    ...see? I'm just placing image index number 4. *The first time I press the button, it loads the proper image, index #4, and the next time, I get the error.

    It seems that the error is generated whenever I try to load an image that was previously loaded. *If I try to repeat a previously-shown image, then error.

    Can anyone help?
    Thanks,
    /S
     
  2. StevenMiles thread starter macrumors newbie

    Joined:
    May 24, 2009
    #2
    Well, no responses, and I really need some help, so I simplified my non-working program and distilled out just the problem.

    Now the project has two buttons. One button loads one .png into the imageview, and the other button loads in a different .png. If I click one button more than once, the program crashes, or if I hit one button, then the other, and then the first again, the program crashes. The crash happens on the line
    [imgShown setImage:img];
    and the debugger says:
    objc_msgSend

    The .pngs are in my resources folder.

    Here is the entire code of the project:
    the .m file:
    Code:
    @interface TestLoadImagesViewController : UIViewController {
    IBOutlet UIImageView *imgShown;
    }
    @property (nonatomic, retain) UIImageView *imgShown;
    -(IBAction)loadMichael:(id)sender;
    -(IBAction)loadSasha:(id)sender;
    the .h file:
    Code:
    #import TestLoadImagesViewController.h
    @implementation TestLoadImagesViewController
    @synthesize imgShown;
    
    -(IBAction)loadMichael:(id)sender {
    NSString *strNextImage = @MikeHorse.png;
    UIImage *img = [UIImage imageNamed:strNextImage];
    if (img != nil) {
    [imgShown setImage:img];
    [img release];
    }
    else {
    //show me an alert here. The alert does not show during testing.
    }
    [strNextImage release];
    }
    
    -(IBAction)loadSasha:(id)sender {
    NSString *strNextImage = @SashaTeeth.png;
    UIImage *img = [UIImage imageNamed:strNextImage];
    if (img != nil) {
    [imgShown setImage:img];
    [img release];
    }
    else {
    // alert code here.
    }
    [strNextImage release];
    }
    I'd love some help with this.
    Thanks.
    /S
     
  3. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #3
    You're releasing objects that you don't own. Remove the [strNextImage release]; and [img release]; lines.

    I'd suggest reading up on Cocoa memory management.
     
  4. StevenMiles thread starter macrumors newbie

    Joined:
    May 24, 2009
    #4
    Hi, kainjow,

    Fix worked perfectly.

    I *have* read about memory management, seems like a hundred times, but it's still confusing to me, and I'll go back and crack the books yet again ...

    Appreciate the help!
    /Steve
     
  5. jnic macrumors 6502a

    Joined:
    Oct 24, 2008
    Location:
    Cambridge
    #5
    http://www.stepwise.com/Articles/Technical/HoldMe.html

    Basically, if you don't alloc or retain something, you shouldn't be releasing it. The two objects you were releasing were autoreleased objects (which is what API methods nearly always return), so they were essentially being released twice: once by the system, and then again by you, causing your crash.
     

Share This Page