释放数组会使 xCode 中的应用程序崩溃

发布于 2025-01-03 06:39:31 字数 4634 浏览 3 评论 0原文

为什么我的应用程序在释放数组时崩溃?我已经尝试了几个小时来解决这个问题!如果我不释放它,就会导致内存泄漏。如果我释放它,它会崩溃并出现以下错误: 程序收到信号:“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉薄对峙 2025-01-10 06:39:31

很可能您在某处向数组 charGuardStore 添加了一个 CharGuard 对象,该对象仅由该数组和 charGuards 超级视图保留。

我认为会发生以下情况:

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. 

因此,当您创建 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:

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. 

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文