3

配列内のスプライトを追跡し、それらをレイヤーに追加および削除してから、最終的にそれらを配列からクリアしようとしています。

私は次のコードを使用しています:

Sprite * Trees[50];
Layer * Forest;

Forest =  [Layer node];
Forest.isTouchEnabled = YES;
[self addChild:Forest z:30];

// do this a bunch of times
Trees[0] = [[Sprite spriteWithFile:@"mytree.png"] retain];
[Trees[0] setPosition:cpv(240,160)];
[Forest addChild:Trees[0] z:5];

そして、私が使用するツリーを破壊したいとき:

[Forest removeChild:Trees[0] cleanup:YES];
[Trees[0] release];

私の問題は、Instruments を見ると、そのメモリを再利用していないことです。スプライトを解放することでメモリが解放されると思いました。私はこれを完全に間違っていますか?

4

3 に答える 3

4

cocos2d でシミュレーターを使用している場合、メモリが解放されているように見えないことはわかっています。そのため、何が起こっているかを正確に把握するには、デバイス上で実行する必要があります。

ここでは、 cocos2d とメモリについての良い議論があります。

私が気付いたのは、作成して保持するものはすべて解放する必要があるということですが、これを行うまではメモリから解放されません。

[[TextureMgr sharedTextureMgr] removeAllTextures]; 

それはメモリを解放します。

より大きな例を次に示します。

Sprite * sPopup = [[Sprite spriteWithFile:@"popup.png"] retain];
    sPopup.position = cpv(240,440);
    [self addChild: sPopup z:2];
[sPopup release];

次に、別の関数で sPopup を使用すると、次のようになります。

[[TextureMgr sharedTextureMgr] removeAllTextures]; 

そしてメモリが解放されます。

于 2009-05-14T01:26:20.487 に答える
3

私の疑いは、あなたが「過剰に」保持していることです:

Trees[0] = [[Sprite spriteWithFile:@"mytree.png"] retain];

Trees が関数内のローカル変数である場合、spriteWithFile がオートリリース付きのスプライトを返す場合、保持する必要はありません。

これについては、アップルのドキュメントの遅延リリースに関するセクションで詳しく説明しています。要するに、自動解放の受信者は、そのスコープの期間中、オブジェクトが有効であることが保証されているということです。関数の範囲を超えてオブジェクトが必要な場合 (たとえば、Trees はクラスのプロパティです)、その場合は保持が必要です (または、保持するように構成されたプロパティを合成するだけです)。

追加の保持を発行することにより、保持カウントが常に高すぎる (決して 0 に達しない) 可能性が高くなり、オブジェクトはガベージ コレクションされません。

適切な測定のために、オブジェクトの有効性について説明しているこの段落も確認することをお勧めします。

于 2009-03-21T16:11:18.450 に答える
0

[Trees[x] release] を呼び出しても、配列自体にはまだオブジェクトが含まれているため、Trees[x] = nil などのように、配列からアイテムを「削除」する必要があると思います。

[Forest addChild:z:] も同様に保持を配置するため、Sprite 作成の「保持」も必要ありません (afaik)。

于 2009-04-11T00:13:39.857 に答える