Reputation: 11112
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
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
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