Legoless
Legoless

Reputation: 11112

iOS: UIImage EXC_BAD_ACCESS

I am building a small iPhone only application (iOS SDK 6.0) and I am getting EXC_BAD_ACCESS exception in XCode.

The application has UITableView with custom UITableViewCell. I have implemented the UITableViewCell in a subclass (I call it MyCustomCell here) and added another parameter to the constructor:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier cellImage:(UIImage *)image;

The UIImage is added to contentView of the TableCell in the method, with following code:

imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
imageView.image = image;

[self.contentView addSubview:imageView];

This function is called within the function cellForRowAtIndexPath of course:

static NSString *CellIdentifier = @"MyCustomCell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil)
{
    cell = [[[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier cellImage:self.cellImage] autorelease];
}

return cell;

The cellImage property of the ViewController (also the UITableViewDelegate) is declared as (it is also synthesized):

@property (nonatomic, retain) UIImage* cellImage;

The image is initialized in viewWillAppear method of ViewController with the following line:

cellImage = [UIImage imageNamed:@"my_image_resource.png"];

This code works correctly, but the EXC_BAD_ACCESS appears, when I customize the image with iOS 6.0 only function:

cellImage = [[UIImage imageNamed:@"my_image_resource.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 10, 0, 10) resizingMode:UIImageResizingModeStretch];

Debugging helped me to locate the line that triggers the error - it is in the initWithStyle method of MyCustomCell implementation:

imageView.image = image;

I have looked through many EXC_BAD_ACCESS errors, I also read the tutorial of why does this error appear, but up to this point, I am not deallocating anything. Some object is probably released at this point, but I cannot find which one exactly and how could I fix the problem.

I have also tried creating two properties in ViewController class, one to hold the original image and the other image with insets. It does not solve the problem, however.

Why is this an error? Why it is not working with image with insets? How could I fix this problem?

Thank you.

Upvotes: 1

Views: 2641

Answers (2)

Aaron Wojnowski
Aaron Wojnowski

Reputation: 6480

You've created a property for cellImage, but you're setting it using the instance variable instead of the setter which has been created for you. Since you're passing in an autoreleased object, there is a possibility that it's been released when you try to reference it next time. Try using this below:

[self setCellImage:[[UIImage imageNamed:@"my_image_resource.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 10, 0, 10) resizingMode:UIImageResizingModeStretch]];

Or with this:

self.cellImage = [[UIImage imageNamed:@"my_image_resource.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 10, 0, 10) resizingMode:UIImageResizingModeStretch];

With this code, the image will be retained for you inside of the setter, and next time you try to use it, the memory will still be allocated and you shouldn't have any issues.

Consider also using ARC, if possible, as much of this intricate memory management stuff is handled for you. http://developer.apple.com/library/mac/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

Upvotes: 1

Reinhard Männer
Reinhard Männer

Reputation: 15257

The error appears when you execute the statement imageView.image = image;. Thus, the object image does not exist when this statement is executed. It must have been released before, either explicitly by a [release image] (since you don't use ARC), or implicitly if image is autoreleased (e.g. if you created it with [UIImage imageNamed:...]).
I think the best were to convert your code ARC, as Aaron Wojnowski suggested. Otherwise, check if image can be released unexpectedly.

Upvotes: 2

Related Questions