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

对象是一个持有自定义类的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];

}

如果我在第一个函数中没有自动释放,那么应用程序运行正常。如果我这样做,那么我尝试访问一个dealloced对象([MatchObject position])。

怎么了?!

有帮助吗?

解决方案

听起来你正在引用释放的内存。当您实际释放内存时,它会崩溃,因为您的程序引用了释放的内存。当你不使用autorelease释放它时,它会工作,因为即使存在内存泄漏,系统也不会注意到它,因为实际上没有释放对象,因此对它的引用不会引起问题。

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

其他提示

只是猜测:

我认为 addChild 正在保留该对象,而 removeChild 正在释放该对象。

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

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

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

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

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

在第一个函数(对象的dealloc和第二个函数)中放置一个断点,以查看在第二个调用之前谁将其释放。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top