我有一个带有以下初始化方法的类:
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
StateStack* s = [[StateStack alloc] init];
state = s;
[s push:NONE]; //<--EXC_BAD_ACCESS on load here
[s release];
}
return self;
}
StateStack具有以下初始化代码:
- (id)init {
self = [super init];
if (self) {
NSMutableArray* s = [[NSMutableArray alloc] init];
stack = s;
[s release];
NSLog(@"%d",[stack retainCount]);
}
return self;
}
奇怪的是,如果我删除NSLog行,则EXC_BAD_ACCESS移至StateStack的dealloc方法:
- (void)dealloc {
[stack release]; //<--EXC_BAD_ACCESS
[super dealloc];
}
到处搜索似乎表明EXC_BAD_ACCESS是由过度释放引起的,但是我看不到我是如何过度释放的。有人知道原因是什么吗?
最佳答案
在init
函数中:
StateStack* s = [[StateStack alloc] init];
state = s;
[s push:NONE]; //<--EXC_BAD_ACCESS on load here
[s release];
您正在分配
StateStack
的实例;它的保留计数为1。然后,在调用release
的函数结束时,保留计数变为0,并且对象已准备好释放。因此,当以后执行dealloc
时,会将state
ivar发送给另一个release
,这将导致错误的访问。您不需要释放s,因为您希望保留该状态。在另一个init方法中会发生相同的错误模式。这是正确的:
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
StateStack* s = [[StateStack alloc] init];
state = s;
[s push:NONE]; //<--EXC_BAD_ACCESS on load here
}
return self;
}
- (id)init {
self = [super init];
if (self) {
NSMutableArray* s = [[NSMutableArray alloc] init];
stack = s;
}
return self;
}
注意:我不想引起误解。使用保留计数检查正确的内存分配是没有用的。这是真的。无论如何,根据保留计数进行推理有助于了解分配/释放/自动释放对象时发生的情况。这是基本机制,但是要跟踪其使用情况以检查内存管理的正确性太困难了。
关于objective-c - 寻找EXC_BAD_ACCESS的原因,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6823053/