何千もの画像を処理する OSX Cocoa ARC プロジェクトがあります。画像の数を減らすために、画像をスキャンして均一な色であるかどうかを確認し、均一な色である場合は画像を破棄してその色を追跡します。
単色を取得するコードは次のとおりです。
- (NSColor *)getSolidColor:(NSImage *)image
{
NSBitmapImageRep* raw_img = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];
int Bpr = [raw_img bytesPerRow],spp = [raw_img samplesPerPixel];
unsigned char *data = [raw_img bitmapData];
int w = [raw_img pixelsWide],h = [raw_img pixelsHigh];
uint32_t mask = 0x00FFFFFF;
uint32_t color = *((uint32_t *)data) & mask;
for( int y=0; y<h; y++ )
{
unsigned char *p = data + Bpr*y;
for( int x=0; x<w; x++ )
{
if( color != (*((uint32_t *)p) & mask) )
return( nil );
p += spp;
}
}
return( [raw_img colorAtX:0 y:0] );
}
(簡潔にするためにいくつかのエラー チェックを削除しました。上記のコードでは、1 ピクセルあたり 3 つのサンプルを想定しています。)
それを呼び出すコードは基本的に次のとおりです。
NSString *imageFile;
while( imageFile = [self getNextImageFile] )
{
NSImage *image = [[NSImage alloc] initWithContentsOfFile:imageFile];
if( [image isValid] && [self getSolidColor:image] )
[fileManager removeItemAtPath:imageFile error:nil];
}
問題は、アプリケーションが異常な量のメモリを消費することです。プロファイラーで実行すると、使用されているメモリの 90% が [NSImage TIFFRepresentation] によって割り当てられていることが示されます (上記の太字)。
つまり、TIFFRepresentation データと NSBitmapImageRep は、関数が戻るとすぐにスコープから外れても決して解放されません。
なんで?そして、ARCにそれらのブロックを強制的に解放させるにはどうすればよいですか?
非 ARC を使用する「古い方法」では、画像の while ループ内に自動解放プールを配置するだけで、問題は解決します。ARCにそのような概念はありますか?
ありがとう。
(PS. NSZombies は有効になっていません。)