我有一个实例变量被定义并合成为如下属性:
@interface CardFrontView : GenericCardView {
UIImage *_letterImage;
}
@property (nonatomic, retain) UIImage *letterImage;
@end
@implementation CardFrontView
@synthesize letterImage = _letterImage;
...
我在letterImage
中设置了-init
属性:
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self != nil) {
NSString *filename = [[NSBundle mainBundle] pathForResource:@"fehu" ofType:@"png"];
self.letterImage = [UIImage imageWithContentsOfFile:filename];
} return self;
}
然后,我在-dealloc
中发布它,然后应用程序崩溃(EXC_BAD_ACCESS
):
- (void)dealloc {
[super dealloc];
[_letterImage release];
}
但是,我无法弄清楚应用程序崩溃的原因。有没有人知道这笔交易是什么?
答案 0 :(得分:20)
好的......从问题和评论中留下的线索中拼凑起来。
首先,这个:
- (void)dealloc {
[super dealloc];
[_letterImage release];
}
是错的,可能是本身崩溃的根源。您告诉拥有_letterImage
的实例dealloc 然后告诉_letterImage
释放。在调用[_letterImage release]
时,包含_letterImage
的对象已经死亡并且已经消失。
虽然可能导致崩溃,但可能不是(但仍应修复)。在评论中,你说:
当我移动[super dealloc]时,我发现失败消失了。 GenericCardView没有什么奇怪的 所有(只是一些预配置 是几种不同的常见的
Card
S)。所以,我不知道为什么会这样 发生了,这一切都让我相当 不舒服。
所有dealloc
方法都应该始终调用[super dealloc];
作为 -dealloc
方法实现中的最后一行代码 。始终无例外*。
当您移除对[super dealloc]
的来电时,任何内容都会开始有效,100%保证会在您的代码中显示错误。
在这种情况下,我不会对您的GenericCardView
类错误地管理实例变量感到惊讶。我首先回顾一下该类dealloc
方法中发布的所有变量,以确保它们首先得到正确管理(同时还要检查dealloc的实现本身)。
无论如何,这有点像过度释放问题。将代码恢复到崩溃发生的状态,然后使用Instrument的僵尸检测工具查看它们是否捕获崩溃并识别过度释放的对象。即使真正的原因只是 ,但您没有在[super dealloc]
方法中最后调用dealloc
,请确认 是案件应该提高你的舒适度。
*实际上有一个例外;当你编写自己的根类时。但这种情况非常罕见,以至于不计算在内。 (快乐,盖伊?:)
答案 1 :(得分:3)
除了要求您发布的约定或其他方面,您的代码的真正问题是[super dealloc]后跟其他任何内容。调用该方法后,您不能再在对象中执行任何操作。
相反,首先进行本地清理,只有在完成后才调用超级。
它基本上与init方法相反,在超级初始化调用之前你不能做任何有用的事情。
亚历
答案 2 :(得分:1)
您是否曾在代码中的任何其他位置访问此内容?我唯一能想到的就是它被释放到其他地方而没有先被保留。
它也可能 - 虽然我非常怀疑这一点 - 是因为你的[super dealloc]
电话是第一次,而不是最后一次。虽然把它放在最后是好的做法,但我觉得它没有任何功能差异 - 你在超类中做了什么奇怪的事情可能会导致它?