调用retain,retainCount分析EXC_BAD_ACCESS并发布

时间:2012-02-20 14:53:43

标签: objective-c memory-management exc-bad-access

我是一名刚接触Objective C的java程序员,所以请保持温和:)

我在一个对象上调用release时遇到错误消息,说EXC_BAD_ACCESS: 我在这个网站上阅读了文档和主题,但是我看到的数据令我感到困惑

- (void) dealloc {
    NSLog(@"dealloc in image Retain count: %i", [image retainCount]);

  [image release];//method throwing EXC_BAD_ACCESS
  ..............
}

记录的保留计数为:1

在导致dealloc的代码中我有:

UIImage *scrn = [[UIImage alloc] initWithCGImage:newImage];
NSLog(@"in after instantiation Retain count: %i", [scrn retainCount]);// logs retain count of 1
CGImageRelease(newImage);
Decoder *d = [[Decoder alloc] init];
.....
NSLog(@"in before decoding Retain count: %i", [scrn retainCount]);// logs retain count of 1
decoding = [d decodeImage:scrn cropRect:cropRect] == YES ? NO : YES;
NSLog(@"in after decoding Retain count: %i", [scrn retainCount]); // logs retain count of 2
[d release]; // this line causes invocation of dealloc on the previous code sniplet
[scrn release];

在decodeImage中,以下是:

- (BOOL) decodeImage:(UIImage *)i cropRect:(CGRect)cr {
NSLog(@"Decoder.mm.decodeImage initial Retain count i : %i retaincount image %i", [i retainCount], [image retainCount]); //logs: Decoder.mm.decodeImage initial Retain count i : 1 retaincount image 0
[self setImage: i];
NSLog(@"Decoder.mm.decodeImage after setting image Retain count i : %i retaincount image %i", [i retainCount], [image retainCount]);//logs: Decoder.mm.decodeImage after setting image Retain count i : 2 retaincount image 2

.......
return [self decode];
}

有几件事困扰着我:

  1. 通过调用retain或通过实例化一个新对象来增加retainCount,而不是像在self setImage中那样将一个var赋值给另一个var:i];但是我看到零售额增加了一个
  2. 在调用[d release]之前,记录的retainCount为2,在方法dealloc中计数为1
  3. 如果计数为1,为什么我会得到EXC_BAD_ACCESS ???
  4. 编辑:按要求添加其他代码

    @implementation Decoder
    
    @synthesize image;
    

    上面的第三个代码片段中提到了图像的设置。

1 个答案:

答案 0 :(得分:3)

保留计数也可以由系统(对于内置类型)以及使用retaincopy属性定义的属性递增。您只负责您所导致的(不是系统保留),但在尝试确定您获得EXC_BAD_ACCESS的原因时,不依赖于保留计数。 XCode有一些很好的内置分析工具,可以更好地跟踪访问错误。

需要注意的一件重要事项是:即使您在计数为1时发布,您的重新计算金额也不会低于1。

有关retaountount的详细信息,请参阅this问题。