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をコメントアウトしたら、ちゃんと動くようになりましたとさ。
めでたしめでたし。