为什么我的应用程序在发布数组时会崩溃?我一直在试图解决这个问题!如果我不释放它,它会导致内存泄漏。如果我确实发布它,它会崩溃并出现此错误: 程序接收信号:“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,然后释放它,但我只能做其中一个。很奇怪!
答案 0 :(得分:1)
你很可能在某个地方向charGuardStore数组添加了一个CharGuard
对象,该数组仅由此数组和charGuards superview保留。
以下是我的想法:
for (CharGuard* charGuard in charGuardStore) {
[charGuard removeFromSuperview]; // charGuard only retained by charGuardStore (= 1 retain left)
[charGuardToDestroy addObject:charGuard]; // charGuard retained by charGuardToDestroy too (= 2 retains left)
}
for (CharGuard* charGuard in charGuardToDestroy){
[charGuardStore removeObject:charGuard]; // remove 1 retain (= 1 retain left) because it's still in charGuardToDestroy
}
/* more code */
[charGuardToDestroy release]; // remove all charGuards. charGuard gets released. And most likely you access it later.
因此,当您创建CharGuards时,很可能已经发生了错误。可能过度释放,但效果会在很晚之后出现。
使用NSZombieEnabled确定是否属于这种情况。
我认为如果在从该阵列中删除charGuards后添加[charGuardToDestroy removeAllObjects];
,它将崩溃。这将证实我说的话。