オブジェクト内のピクセルに関する基本的な情報を保持しようとしています。基本的には、(1) ピクセルがクリアであるかどうか、および (2) ピクセルがサーフェス エッジであると定義している対象上にあるかどうかです。次のクラスを使用してオブジェクトを定義しています。
@interface PixelInfo : NSObject
@property (nonatomic, assign) BOOL isClear;
@property (nonatomic, assign) BOOL isEdge;
@end
ただし、メモリ不足の問題が発生しています。このオブジェクトを使用して、破壊可能な環境を持つゲームでピクセルの状態を追跡しています。問題は、iPad Retina サイズの画像 (2048 x 1536 = 300 万ピクセル) の場合、これらのオブジェクトを 300 万個作成していて、数百 MB のメモリを割り当てているように見え、iPhone デバイスが原因で強制終了していることです。メモリ不足の問題に。
iPhone デバイス内のログを見ると、次の情報が得られます。
Name rpages recent_max [reason] (state)
MyApp 166400 166400 [per-process-limit] (frontmost) (resume)
Instruments Allocations ツールを使用すると、時間の経過とともに数百 MB のメモリが PixelInfo オブジェクトに割り当てられ、最終的に iPhone デバイスが強制的に終了することがわかります。
これに基づいて、このようなピクセル情報を保持するべきではないのではないかと推測しています。また、Instruments Allocations が、デバイスがこれを達成するために数百 MB のメモリを必要としていることを示しているのではないかと疑っています。他の場所で問題が発生している可能性がありますが、特定できないようです。
すべてのピクセルの状態を追跡する必要があると感じています。このピクセル情報を使用して、環境を破棄しているときにイメージの状態を追跡し (つまり、ピクセル情報isClear
プロパティを YES に設定し、isEdge
プロパティを NO に設定)、環境の影響を受ける部分の新しいエッジを再計算します。
ここに私の主な質問があります:
- 配列内に 300 万個のオブジェクトを保持しようとしているのは悪いことですか?
- メモリ不足は明らかに問題ですが (Instruments Allocations ツールを使用して確認できます)、これらの 300 万個のオブジェクトで数百 MB のメモリを使用する必要があるということは正しいのでしょうか? それとも、何か他の原因で問題が発生している可能性が高いのでしょうか?
この状況をさらにデバッグする方法についての考えや指針は、本当に役に立ちます。前もって感謝します。
-- 追加のコンテキスト (関連する場合) のために、これはテクスチャからピクセル情報を読み取って保存する方法です (いくつかの cocos2d クラスを使用):
unsigned char data[4];
// create texture to read pixel data from
CCRenderTexture *renderTexture = [[CCRenderTexture alloc] initWithWidth:widthInPoints
height:heightInPoints
pixelFormat:kCCTexture2DPixelFormat_RGBA8888];
[renderTexture beginWithClear:1 g:1 b:1 a:0];
// self.view is a CCSprite object and the visit method draws it to the texture so I can read the pixels
[self.view visit];
for (int i = 0; i < heightInPixels; ++i) {
for (int j = 0; j < widthInPixels; ++j) {
// read pixel data
CGPoint pixelPoint = ccp(j, i);
glReadPixels(pixelPoint.x, pixelPoint.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
// store pixel data in PixelInfo object; read alpha value in data
PixelInfo *pixelInfo = [[PixelInfo alloc] init];
pixelInfo.isClear = [self _isPixelClear:data];
// add object to _pixelData array (NSMutableArray object)
[_pixelData addObject:pixelInfo];
[pixelInfo release];
}
}
// release texture
[renderTexture end];
[renderTexture release];