メモリーリーク:Xcode と Instruments:その2

カメラを使うアプリを作っていて、メモリリークでアプリが落ちる、それを調べるのに Instruments が有効だと書きました。でも、Instruments で検出できない leak もあり、memory をモニタリングしつつ使われている method を掌握しつつ、根本的な問題解決へ向け、色々調べ、ようやく分かりました。

delegate method の captureOutput:didOutputSampleBuffer:fromConnection 内で UIImage を生成。この delegate method は、カメラ(厳密には movie)使用中、ガンガン呼ばれているのを確認。delegate method 内で生成した UIImage が解放されず、どんどんメモリを消費。終いにはメモリを食い尽くしてしまい、安全面から OS に kill される・・・と、まあ、このような現象だと。頼むよ ARC・・・。

原因がわかったので対策を。
使い終わった UIImage を解放してやればよいのですが、ここでハマる。CGImage の場合、ご丁寧に、CGImageRelease() という method ? primitive? が用意されている。さて、UIImage の場合は UIImageRelease だろ、と思ったら、そんな method は存在しない・・・うっっ どうすんのこれ。苦肉の策で someUiImage = nil; とかしてもダメ。ネットを検索してみたら、ARC が利かないなら @autoreleasepool を使え、とのことで、いろいろやってみたけれど、状況は改善せず。叱られると思いつつも、[someUiImage release]; とかやって、やっぱり叱られる。release は ARC に任せてくれよとか言ってくる始末。任せたけどダメだったからやってんだろと、文句を言いたくなる。

ここで脳内に神降臨。こんな方法を思いつく。
CGImageRelease( someUiImage.CGImage );
CGImageRelease が通るように、無理やりCGImage を生成するという荒技。これが功を奏し、アプリが落ちなくなった。

Instruments でメモリ監視すると、メモリが騰がったり下がったりで、うまく機能しているようだ。
正しい方法かわからないけれども、上手くいったのでこれでよしとしよう。ってか、頼むよ ARC ・・・