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 position]) にアクセスしようとします。

どうしたの?!

4

4 に答える 4

1

ただの大げさな推測:

addChildがオブジェクトを保持し、removeChildがオブジェクトを解放していると思います。

しかし、removeChildがオブジェクトを見つけられない場合(つまり、子でない場合)はどうなりますか?その場合もオブジェクトを解放しますか?(それはすべきではありません)

于 2009-09-14T20:43:16.873 に答える
1

解放されたメモリを参照しているようです。実際にメモリを解放すると、プログラムが解放されたメモリを参照するため、メモリがクラッシュします。autorelease を使用して解放しない場合でも、オブジェクトが実際に解放されていないため、メモリ リークが発生してもシステムがそれに気付かないため、オブジェクトへの参照が問題を引き起こさないため、動作します。

それでは、虫眼鏡を取り出してコードをもう一度見て、デバッガーの使用を開始してください...楽しんでください:)

于 2009-09-14T20:32:16.973 に答える
0

オブジェクトを解放する「removeChild」メソッドで何かをしている可能性はありますか? あなたが投稿したコードに問題はないようです...

于 2009-09-14T20:28:20.907 に答える
0

最初の関数は init に似ていない関数であり、init を呼び出しているため、最初の関数で自動解放する必要があります。

最初の関数の最後では、保持を引き起こした配列にオブジェクトを追加したため、オブジェクトはまだ有効です。

最初の関数が呼び出されてから 2 番目の関数が呼び出されるまでの間に、誰かがオブジェクトを解放しているため、オブジェクトへのアクセスがクラッシュしています。

最初の関数、オブジェクトの dealloc 、および 2 番目の関数にブレークポイントを配置して、2 番目の呼び出しの前に誰がそれを解放しているかを確認します。

于 2013-03-04T03:41:43.283 に答える