释放数组会使 xCode 中的应用程序崩溃
为什么我的应用程序在释放数组时崩溃?我已经尝试了几个小时来解决这个问题!如果我不释放它,就会导致内存泄漏。如果我释放它,它会崩溃并出现以下错误: 程序收到信号:“EXC_BAD_ACCESS”。 有时也这样说: 数据格式化程序暂时不可用,将在“继续”后重试。 (此时调用 dlopen 不安全。)
就是无法解决。有很多代码,所以我将粘贴(我认为的)相关部分。
-(void)startGame:(int)levelNumber {
//NOTE there is some code ive not pasted as its too big, but I dont think its relevant
levelsArray = [gameLevels loadLevelMap:levelNumber];
levelsArray_charGuards = [[levelsArray objectAtIndex:4]retain];
//CREATE CHAR MAIN ########
charMainStore = [[NSMutableArray arrayWithCapacity:1] retain];
charMainToDestroy = [[NSMutableArray arrayWithCapacity:1] retain];
CharMain* charMain = [[CharMain alloc] initWithFrame:CGRectMake(((levels_charStart_x)*40), ((levels_charStart_y)*40), 0, 0)];
[viewController.mapView addSubview:charMain];
[self registerMainChar:charMain];
charMain.gameController = self;
charMain.currentGrid_x = levels_charStart_x;
charMain.currentGrid_y = levels_charStart_y;
charMain.nextGrid_x = levels_charStart_x;
charMain.nextGrid_y = levels_charStart_y;
mapViewController.gameController = self;
[self moveMap_x:((levels_charStart_x)*40) moveMap_y:((levels_charStart_y)*40)];
[charMain release];
//CREATE CHAR GUARD ########
charGuardStore = [[NSMutableArray arrayWithCapacity:10] retain];
charGuardToDestroy = [[NSMutableArray arrayWithCapacity:10] retain];
//These are both @synthesize properly
//levelsArray_charGuards is from previously
for (NSMutableArray* levelsArray_charGuards_path in levelsArray_charGuards) {
NSMutableArray* levelsArray_charGuards_path_eachCoOrd = [levelsArray_charGuards_path objectAtIndex:0];
int levels_charGuardStart_x = [[NSString stringWithFormat:@"%@",[levelsArray_charGuards_path_eachCoOrd objectAtIndex:0]] intValue];
int levels_charGuardStart_y = [[NSString stringWithFormat:@"%@",[levelsArray_charGuards_path_eachCoOrd objectAtIndex:1]] intValue];
CharGuard* charGuard = [[CharGuard alloc] initWithFrame:CGRectMake((levels_charGuardStart_x*40), (levels_charGuardStart_y*40), 0, 0)];
//CharGuard* charGuard = [[CharGuard alloc] initWithFrame:CGRectMake(((levels_charStart_x)*40), ((levels_charStart_y)*40), 0, 0)];
[viewController.mapView addSubview:charGuard];
[self registerGuardChar:charGuard];
charGuard.gameController = self;
[charGuard setImage];
charGuard.currentGrid_x = levels_charGuardStart_x;
charGuard.currentGrid_y = levels_charGuardStart_y;
charGuard.nextGrid_x = levels_charGuardStart_x;
charGuard.nextGrid_y = levels_charGuardStart_y;
mapViewController.gameController = self;
charGuard.levelsArray_charGuards_path = levelsArray_charGuards_path;
[charGuard release];
charGuard = nil;
levelsArray_charGuards_path = nil;
levelsArray_charGuards_path_eachCoOrd =nil;
}
}
当一个级别完成或重新启动时,这被称为:
-(void)clearLevel {
NSLog(@"Clear Level");
for (CharMain* charMain in charMainStore){
[charMain removeFromSuperview];
[charMainToDestroy addObject:charMain];
}
for (CharMain* charMain in charMainToDestroy){
[charMainStore removeObject:charMain];
}
for (CharGuard* charGuard in charGuardStore) {
[charGuard removeFromSuperview];
[charGuardToDestroy addObject:charGuard];
}
for (CharGuard* charGuard in charGuardToDestroy){
[charGuardStore removeObject:charGuard];
}
[charGuardStore release];
charGuardStore=nil;
[charMainStore release];
charMainStore=nil;
//[charGuardToDestroy release]; //If I allow this it crashes!***********
charGuardToDestroy= nil;
[charMainToDestroy release];
charMainToDestroy = nil;
}
游戏然后再次调用 startGame:(int)levelNumber。
我还有其他对象,我没有在这里展示,但它们都工作正常。只是charGuardToDestroy不想被释放!
我试过:
-(void)clearLevel {
NSLog(@"Clear Level");
for (CharMain* charMain in charMainStore){
[charMain removeFromSuperview];
[charMainToDestroy addObject:charMain];
}
for (CharMain* charMain in charMainToDestroy){
[charMainStore removeObject:charMain];
}
for (CharGuard* charGuard in charGuardStore) {
[charGuard removeFromSuperview];
//[charGuardToDestroy addObject:charGuard];
}
/*
for (CharGuard* charGuard in charGuardToDestroy){
[charGuardStore removeObject:charGuard];
}
*/
[charGuardStore release];
charGuardStore=nil;
[charMainStore release];
charMainStore=nil;
[charGuardToDestroy release]; //I tried allowing this and removing the above code ***********
charGuardToDestroy= nil;
[charMainToDestroy release];
charMainToDestroy = nil;
}
这也有效,但为什么?我确实需要能够从屏幕和数组中删除 charGuard,然后释放它,但我只能执行其中之一。很奇怪!
why does my app crash when releasing an array? Ive been trying to figure it out for HOURS! If I dont release it, it causes a memory leak. If I do release it, it crashes with this error:
Program received signal: “EXC_BAD_ACCESS”.
Sometimes it also says this:
Data Formatters temporarily unavailable, will re-try after a 'continue'. (Not safe to call dlopen at this time.)
Just cant work it out. Theres alot of code, so i will paste (what i think) is the relevant parts.
-(void)startGame:(int)levelNumber {
//NOTE there is some code ive not pasted as its too big, but I dont think its relevant
levelsArray = [gameLevels loadLevelMap:levelNumber];
levelsArray_charGuards = [[levelsArray objectAtIndex:4]retain];
//CREATE CHAR MAIN ########
charMainStore = [[NSMutableArray arrayWithCapacity:1] retain];
charMainToDestroy = [[NSMutableArray arrayWithCapacity:1] retain];
CharMain* charMain = [[CharMain alloc] initWithFrame:CGRectMake(((levels_charStart_x)*40), ((levels_charStart_y)*40), 0, 0)];
[viewController.mapView addSubview:charMain];
[self registerMainChar:charMain];
charMain.gameController = self;
charMain.currentGrid_x = levels_charStart_x;
charMain.currentGrid_y = levels_charStart_y;
charMain.nextGrid_x = levels_charStart_x;
charMain.nextGrid_y = levels_charStart_y;
mapViewController.gameController = self;
[self moveMap_x:((levels_charStart_x)*40) moveMap_y:((levels_charStart_y)*40)];
[charMain release];
//CREATE CHAR GUARD ########
charGuardStore = [[NSMutableArray arrayWithCapacity:10] retain];
charGuardToDestroy = [[NSMutableArray arrayWithCapacity:10] retain];
//These are both @synthesize properly
//levelsArray_charGuards is from previously
for (NSMutableArray* levelsArray_charGuards_path in levelsArray_charGuards) {
NSMutableArray* levelsArray_charGuards_path_eachCoOrd = [levelsArray_charGuards_path objectAtIndex:0];
int levels_charGuardStart_x = [[NSString stringWithFormat:@"%@",[levelsArray_charGuards_path_eachCoOrd objectAtIndex:0]] intValue];
int levels_charGuardStart_y = [[NSString stringWithFormat:@"%@",[levelsArray_charGuards_path_eachCoOrd objectAtIndex:1]] intValue];
CharGuard* charGuard = [[CharGuard alloc] initWithFrame:CGRectMake((levels_charGuardStart_x*40), (levels_charGuardStart_y*40), 0, 0)];
//CharGuard* charGuard = [[CharGuard alloc] initWithFrame:CGRectMake(((levels_charStart_x)*40), ((levels_charStart_y)*40), 0, 0)];
[viewController.mapView addSubview:charGuard];
[self registerGuardChar:charGuard];
charGuard.gameController = self;
[charGuard setImage];
charGuard.currentGrid_x = levels_charGuardStart_x;
charGuard.currentGrid_y = levels_charGuardStart_y;
charGuard.nextGrid_x = levels_charGuardStart_x;
charGuard.nextGrid_y = levels_charGuardStart_y;
mapViewController.gameController = self;
charGuard.levelsArray_charGuards_path = levelsArray_charGuards_path;
[charGuard release];
charGuard = nil;
levelsArray_charGuards_path = nil;
levelsArray_charGuards_path_eachCoOrd =nil;
}
}
When one level is finished, or is restarted, this is called:
-(void)clearLevel {
NSLog(@"Clear Level");
for (CharMain* charMain in charMainStore){
[charMain removeFromSuperview];
[charMainToDestroy addObject:charMain];
}
for (CharMain* charMain in charMainToDestroy){
[charMainStore removeObject:charMain];
}
for (CharGuard* charGuard in charGuardStore) {
[charGuard removeFromSuperview];
[charGuardToDestroy addObject:charGuard];
}
for (CharGuard* charGuard in charGuardToDestroy){
[charGuardStore removeObject:charGuard];
}
[charGuardStore release];
charGuardStore=nil;
[charMainStore release];
charMainStore=nil;
//[charGuardToDestroy release]; //If I allow this it crashes!***********
charGuardToDestroy= nil;
[charMainToDestroy release];
charMainToDestroy = nil;
}
The game then calls startGame:(int)levelNumber again.
I have other object which i havnt shown here but they all work fine. Its just the charGuardToDestroy that doesnt want to be released!
I have tried:
-(void)clearLevel {
NSLog(@"Clear Level");
for (CharMain* charMain in charMainStore){
[charMain removeFromSuperview];
[charMainToDestroy addObject:charMain];
}
for (CharMain* charMain in charMainToDestroy){
[charMainStore removeObject:charMain];
}
for (CharGuard* charGuard in charGuardStore) {
[charGuard removeFromSuperview];
//[charGuardToDestroy addObject:charGuard];
}
/*
for (CharGuard* charGuard in charGuardToDestroy){
[charGuardStore removeObject:charGuard];
}
*/
[charGuardStore release];
charGuardStore=nil;
[charMainStore release];
charMainStore=nil;
[charGuardToDestroy release]; //I tried allowing this and removing the above code ***********
charGuardToDestroy= nil;
[charMainToDestroy release];
charMainToDestroy = nil;
}
This also worked, but why?? I really need to be able to remove the charGuard from the screen, and from the array, then release it, but I can only do one or the other. Its strange!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
很可能您在某处向数组 charGuardStore 添加了一个
CharGuard
对象,该对象仅由该数组和 charGuards 超级视图保留。我认为会发生以下情况:
因此,当您创建 CharGuard 时,您的错误很可能已经发生了。可能是过度释放,但效果要晚得多才能显现出来。
使用 NSZombieEnabled 来确定是否是这种情况。
我认为如果您在从该数组中删除 charGuards 后添加
[charGuardToDestroy removeAllObjects];
,它将崩溃。这将证实我所说的。Most likely you somewhere added a
CharGuard
object to the array charGuardStore which is only retained by this array and charGuards superview.Here is what I think happens:
so most likely your bug happens already when you create the CharGuards. Probably overreleasing, but the effect shows up much much later.
Use NSZombieEnabled to figure out if this is the case.
I think if you add
[charGuardToDestroy removeAllObjects];
after you have removed the charGuards from that array it will crash. This would confirm what I said.