Question

I have the following method in UIImageManipulation.m:

+(UIImage *)scaleImage:(UIImage *)source toSize:(CGSize)size
{
    UIImage *scaledImage = nil;
    if (source != nil)
    {
        UIGraphicsBeginImageContext(size);
        [source drawInRect:CGRectMake(0, 0, size.width, size.height)];
        scaledImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    return scaledImage;
}

I am calling it in a different view with:

imageFromFile = [UIImageManipulator scaleImage:imageFromFile toSize:imageView.frame.size];

(imageView is a UIImageView allocated earlier)

This is working great in my code. I resizes the image perfectly, and throws zero errors. I also don't have anything pop up under build -> analyze. But the second I turn on NSZombieEnabled to debug a different EXC_BAD_ACCESS issue, the code breaks. Every single time. I can turn NSZombieEnabled off, code runs great. I turn it on, and boom. Broken. I comment out the call, and it works again. Every single time, it gives me an error in the console: -[UIImage release]: message sent to deallocated instance 0x3b1d600. This error doesn't appear if `NSZombieEnabled is turned off.

Any ideas?

--EDIT--

Ok, This is killing me. I have stuck breakpoints everywhere I can, and I still cannot get a hold of this thing. Here is the full code when I call the scaleImage method:

-(void)setupImageButton
{
    UIImage *imageFromFile;

    if (object.imageAttribute == nil) {
        imageFromFile = [UIImage imageNamed:@"no-image.png"];
    } else {
        imageFromFile = object.imageAttribute;
    }
    UIImage *scaledImage = [UIImageManipulator scaleImage:imageFromFile toSize:imageButton.frame.size];
    UIImage *roundedImage = [UIImageManipulator makeRoundCornerImage:scaledImage :10 :10 withBorder:YES];
    [imageButton setBackgroundImage:roundedImage forState:UIControlStateNormal];
}

The other UIImageManipulator method (makeRoundCornerImage) shouldn't be causing the error, but just in case I'm overlooking something, I threw the entire file up on github here.

It's something about this method though. Has to be. If I comment it out, it works great. If I leave it in, Error. But it doesn't throw errors with NSZombieEnabled turned off ever.

Was it helpful?

Solution

The purpose of NSZombieEnabled is to detect messages that get sent to objects after they've been deallocated. The console error you're seeing is NSZombieEnabled telling you that a release message is being sent to a deallocated instance of UIImage. Usually a bug like this is the result of too many calls to release, or not enough calls to retain.

In this case, your scaleImage:toSize: method returns an autoreleased UIImage. The error message you're getting from NSZombieEnabled suggests that you may be releasing this object after it gets returned. This would explain your bug. When your autorelease pool drains it would try to release an object that's already been deallocated.

You're passing imageFromFile to scaleImage:toSize:, and then reassigning that same variable to the return value. There's nothing wrong with this idiom per se, but does require some extra care to avoid memory bugs like this one. You're overwriting your reference to the original object, so you either have to make sure it's autoreleased before the assignment, or save a separate reference that you can manually release after the assignment. Otherwise your original object will leak.

OTHER TIPS

The error was due to a release going on in the makeRoundedCornerImage method from UIImageManipulator. Still not sure why it wasn't getting picked up without NSZombieEnabled turned on, but that's what it was.

You can find the offending line in the Gist I posted in the original question: Line 74.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top