调用retain,retainCount分析EXC_BAD_ACCESS和release
我是一位刚接触 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];
}
有几件事让我困惑:
- 在 理解保留计数是通过调用保留或实例化一个新对象来增加的,而不是像 self setImage: i]; 中那样通过将一个变量分配给另一个变量来增加。但是我看到保留计数增加了 1
- 在调用 [d release] 之前记录的保留计数是 2,在方法 dealloc 中计数是 1
- 如果计数是 1,为什么我会得到 EXC_BAD_ACCESS ???
编辑:根据要求添加附加代码
@implementation Decoder
@synthesize image;
图像的设置在上面的第三个代码片段中提到。
I'm a java programmer new to Objective C, so please be gentle :)
I'getting an errorr message saying EXC_BAD_ACCESS
on calling release on an object:
I read documentation and threads on this site, but I see data that's confusing me
- (void) dealloc {
NSLog(@"dealloc in image Retain count: %i", [image retainCount]);
[image release];//method throwing EXC_BAD_ACCESS
..............
}
the logged retain count is: 1
In the code that is causing the dealloc I have:
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];
In decodeImage the following is going on:
- (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];
}
There are several things puzzeling me:
- From what understood the retainCount is increased by calling retain or by instantiating a new object, not by assigningment of one var to another as is done in self setImage: i]; however i see that the retaincount is increased by one
- Before calling [d release] the logged retainCount is 2, in the method dealloc the count is 1
- If the count is 1, why do I get the EXC_BAD_ACCESS ???
Edit: added additional code as requested
@implementation Decoder
@synthesize image;
The setting of image is mentioned in the third code sniplet above.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
保留计数还可以通过系统(对于内置类型)以及使用
retain
或copy
属性定义的属性来增加。您只对您造成的问题负责(而不是系统保留的),但在尝试确定为什么获得 EXC_BAD_ACCESS 时,不要依赖保留计数。 XCode 有一些很好的内置分析工具,可以更好地跟踪访问错误。需要注意的一件重要事情:即使您在计数为 1 时释放,保留计数也永远不会低于 1。
请参阅 这个问题提供了有关保留计数的详细信息。
Retain count can also be incremented by the system (for build-in types) and by properties that are defined with the
retain
orcopy
attributes. You're only responsible for the ones you cause (not the system retains), but don't depend on the retain count when trying to determine why you're getting EXC_BAD_ACCESS. XCode has some good build-in analysis tools that are better for tracking down access errors.One important thing to note: your retaincount will never go below 1 even if you release when the count is 1.
See this question for good information on retaincount.