1

在我完成了游戏中困难部分的编码后,我发现了一些内存管理错误。

objects 是一个包含自定义类的 NSMutableArray。

- (void) spawnObjects
{   
    for (int index = 0; index < INITIAL_OBJECTS; index++)
    {
        [objects addObject:[[[MatchObject alloc] initWithImageNameID:(index % 3)] autorelease]];
        [[objects objectAtIndex:index] setPosition:[GameLayer randomPoint]];
    }

    ...
}

我后来使用了这个功能。

- (void) checkAllSprites
{

    NSMutableArray *spritesToDelete = [NSMutableArray array];
    for (int index = 0; index < [points count] - 1; index ++)
    {
        for (MatchObject *planetLike in objects)
        {
            CGPoint point1 = [[points objectAtIndex:index] CGPointValue];
            CGPoint point2 = [[points objectAtIndex:index+1] CGPointValue];
            if ([GameLayer lineIntersectsCircle:point1 :point2 :[planetLike position] :16.0f])
            {

                ParticleSystem *planetDeath = [ParticlePlanetDeath node];
                planetDeath.texture = [[TextureMgr sharedTextureMgr] addImage:@"fire.pvr"];
                planetDeath.position = [planetLike position];
                [self addChild:planetDeath z:0 tag:2];

                [spritesToDelete addObject:planetLike];

                [self removeChild:planetLike cleanup:YES];

            }

        }
    }
    [objects removeObjectsInArray:spritesToDelete];
    [spritesToDelete removeAllObjects];

}

如果我不在第一个函数中自动释放,则该应用程序可以正常工作。如果我这样做了,那么我会尝试访问一个解除分配的对象([MatchObject 位置])。

怎么了?!

4

4 回答 4

1

听起来您正在引用已释放的内存。当您实际释放内存时,它会崩溃,因为您的程序引用释放了内存。当您不使用 autorelease 释放它时,它仍然可以工作,因为即使存在内存泄漏,系统也不会注意到它,因为该对象实际上并未被释放,因此对它的引用不会导致问题。

所以,拿出放大镜,再次查看你的代码,然后开始使用调试器......玩得开心:)

于 2009-09-14T20:32:16.973 回答
1

只是一个疯狂的猜测:

我想addChild正在保留对象,而removeChild正在释放对象。

但是当removeChild没有找到对象时会发生什么(即如果它不是一个孩子)?在那种情况下它是否也会释放对象?(它不应该这样做)

于 2009-09-14T20:43:16.873 回答
0

您是否有可能在“removeChild”方法中做某事最终释放对象?您发布的代码似乎没有任何问题...

于 2009-09-14T20:28:20.907 回答
0

您必须在第一个函数中自动释放,因为它是一个非初始化函数,并且您正在调用一个 init。

在第一个函数结束时,对象仍然有效,因为您将它添加到导致保留的数组中。

在调用第一个函数和调用第二个函数之间,有人正在释放对象,这就是访问对象崩溃的原因。

在第一个函数、对象的 dealloc 和第二个函数中放置一个断点,以查看在第二次调用之前是谁在释放它。

于 2013-03-04T03:41:43.283 回答