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!
Most likely you somewhere added a
CharGuardobject 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.