iOS:UIImage EXC_BAD_ACCESS

时间:2013-02-03 17:09:49

标签: iphone ios objective-c memory-management

我正在构建一个小型iPhone应用程序(iOS SDK 6.0),我在XCode中获得 EXC_BAD_ACCESS 异常。

该应用程序UITableView具有自定义UITableViewCell。我在子类中实现了UITableViewCell(我在这里称之为MyCustomCell)并在构造函数中添加了另一个参数:

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

UIImage已添加到方法中contentView的{​​{1}},代码如下:

TableCell

当然在函数imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)]; imageView.image = image; [self.contentView addSubview:imageView]; 内调用此函数:

cellForRowAtIndexPath

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; 的{​​{1}}属性(也是cellImage)被声明为(它也被合成):

ViewController

使用以下行在ViewController的UITableViewDelegate方法中初始化图像:

@property (nonatomic, retain) UIImage* cellImage;

此代码正常运行,但当我使用iOS 6.0自定义图像功能时,会出现EXC_BAD_ACCESS:

viewWillAppear

调试帮助我找到了触发错误的行 - 它位于MyCustomCell实现的cellImage = [UIImage imageNamed:@"my_image_resource.png"]; 方法中:

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

我查看了很多initWithStyle错误,我还阅读了为什么会出现此错误的教程,但到目前为止,我还没有解除任何问题。有些对象可能在此时被释放,但我找不到哪一个,我怎么能解决这个问题。

我还尝试在ViewController类中创建两个属性,一个用于保存原始图像,另一个用于包含insets。但是,它并没有解决问题。

为什么这是一个错误?为什么它没有使用带插图的图像?我该如何解决这个问题呢?

谢谢。

2 个答案:

答案 0 :(得分:2)

执行语句imageView.image = image;时出现错误。因此,执行此语句时,对象image不存在。它必须在之前被释放,或者由[release image]明确地释放(因为你不使用ARC),或者在image被自动释放时隐式释放(例如,如果你用[UIImage imageNamed:...]创建它)。
我认为最好的是转换你的代码ARC,正如Aaron Wojnowski建议的那样。否则,请检查image是否可以意外释放。

答案 1 :(得分:1)

您已经为cellImage创建了一个属性,但是您使用实例变量而不是为您创建的setter来设置它。由于您传入的是自动释放的对象,因此下次尝试引用它时可能会释放它。请尝试使用以下内容:

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

或者用这个:

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

使用此代码,图像将在setter中保留,下次尝试使用时,内存仍将被分配,您不应该有任何问题。

如果可能的话,还要考虑使用ARC,因为这些复杂的内存管理内容会为您处理。 http://developer.apple.com/library/mac/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html