retainしていないものをreleaseしてはいけない

 どっぷりハマってしまったバグについての忘備録です。


 起こった箇所:画像ファイルを読み込んで、テクスチャを作るメソッドの終わりの [uiImage release];
 起こった症状:有る程度の分量を読み込むと、下のようなエラーで止まる。止まる画像データは同じ。
Assertion failed: (!state->is_singleton), function color_space_state_dealloc, file ColorSpaces/CGColorSpace.c, line 127.


 容疑者A:画像データ
 画像データの読み込みタイミングを変えると、別の画像で同じエラーが起こるようになるし、
取り立ててアヤしい所も無いので釈放。


 容疑者B〜もろもろ:xibファイルの有無から読み込みタイミングとかアレコレ。
 全部シロ。泣きそうになる。


 Xcode4のAnalyzeをかけてみる。こんなご神託を頂く。


◇Incorrect decrement of the reference count of an object that is not owned at this point by the caller
Call to function 'CGImageGetColorSpace' returns a Core Foundation object with a +0 retain count (non-owning reference)
Incorrect decrement of the reference count of an object that is not owned at this point by the caller


 !そう言えば、エラーメッセージにもCGColorSpaceが!
 犯人はUIImageじゃなくて、CGColorSpaceかッ!


 その時のソースコード

	CGColorSpaceRef colorSpace = CGImageGetColorSpace(image); //コイツと

	int memsize = width * height * 4;
	GLubyte* imageData = (GLubyte*)malloc(memsize);
	memset(imageData, 0x0, memsize);
	
	CGContextRef imageContex = CGBitmapContextCreate(
		 imageData, 
		 width, 
		 height, 
		 8, 
		 width*4, 
		 colorSpace, 
		 kCGImageAlphaPremultipliedLast |
		 kCGBitmapByteOrder32Big
	 );
	
	CGColorSpaceRelease(colorSpace); //コイツがアヤシイ


 捜査本部は色めき立ち、聞き取り調査を開始。
 こんな記事を見つける!


COCOA - Does the result of CGImageGetColorSpace(image) have to be released?


 どうやらCGColorSpaceReleaseしてるのがイケナイらしい!
 先のサイトで答えている人は、retainしたらreleaseしなきゃイケナイけど、retainしなかったらreleaseしなくて良いんだよ。
 詳しくはココを読んでごらん、と。


 でリンクの先は、関数名についてのGetルールとCreateルールのお話。Getがついてるのはretainしていない。
 Createがついてるのは、retainしてる、というもの。(部分的に読んだだけだから違ってたらご容赦を)
 というコトは、CGImageGetColorSpaceは、retainしてないから、CGColorSpaceReleaseしちゃイケナイ!


 かくしてCGColorSpaceReleaseをコメントアウトしたら、ちゃんと動くようになりましたとさ。
 めでたしめでたし。


 Analyzeは便利です。このバグとは別に潜在的メモリリークを一つ教えてくれて、解決できました。