释放实例变量会导致崩溃,但为什么呢?

Jon*_*ing 2 iphone memory-management objective-c

我有一个实例变量被定义并合成为一个属性,如下所示:

@interface CardFrontView : GenericCardView {
    UIImage *_letterImage;
}

@property (nonatomic, retain) UIImage *letterImage;

@end

@implementation CardFrontView
@synthesize letterImage = _letterImage;
...
Run Code Online (Sandbox Code Playgroud)

我将该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;
}
Run Code Online (Sandbox Code Playgroud)

然后,我发布它-dealloc,然后应用程序崩溃(EXC_BAD_ACCESS):

- (void)dealloc {
    [super dealloc];
    [_letterImage release];
}
Run Code Online (Sandbox Code Playgroud)

但是,我无法弄清楚应用程序崩溃的原因.有没有人知道这笔交易是什么?

bbu*_*bum 20

好的......从问题和评论中留下的线索中拼凑起来.

首先,这个:

- (void)dealloc {
    [super dealloc];
    [_letterImage release];
}
Run Code Online (Sandbox Code Playgroud)

是错的,可能是崩溃的根源.您告诉拥有_letterImagedealloc 的实例,然后告诉_letterImage释放.在[_letterImage release]调用时,包含的对象_letterImage已经死了并且消失了.

虽然这可能会导致崩溃,但可能不会(但仍应修复).在评论中,你说:

当我移动[super dealloc]时,我发现失败消失了.GenericCardView根本没有什么奇怪的东西(只是一些常见的几种不同的预配置 Card).所以,我不知道为什么会这样,这一切都让我感到很不舒服.

所有的dealloc方法应该始终有一个调用[super dealloc];代码在最后一行-dealloc方法的实现.始终无例外*.

当你删除一个调用时,任何东西开始工作[super dealloc]是100%保证表明你的代码中有一个错误.

在这种情况下,我不会对您的GenericCardView类错误地管理实例变量感到惊讶.我首先回顾一下该类dealloc方法中发布的所有变量,以确保它们首先得到正确管理(同时还要检查dealloc的实现本身).

无论如何,这有点像过度释放问题.将代码恢复到崩溃发生的状态,然后使用Instrument的僵尸检测工具查看它们是否捕获崩溃并识别过度释放的对象.即使真正原因原来是只有你没叫[super dealloc]你过去的dealloc方法,确认是应该增加舒适度的情况下.

*实际上有一个例外; 当你编写自己的根类时.但这种情况非常罕见,以至于不计算在内.(快乐,盖伊?:)