きりかノート 3冊め

おあそびプログラミング

RubyCocoa - retain 漏れの探索 (その1?)

[rubycocoa-devel:427] の話。まずひとつやっつけた。

RubyCocoa では、Ruby 用に 1 だけ retainCount を確保するようになっている。で、Cocoa のオブジェクトが Ruby 世界にあらわれたときに、この処理をするようにしている。ただし、alloc 直後など、オーナーシップの発生以前のオブジェクトは retain しないようにするべきだ。これが apple-unstable (昔の) で導入された改善のひとつだ。(see ocm_retain_result_if_necessary() in mdl_objwrapper.m)このおかげで "NSView not correctly initialized. Did you forget to call super?" はもう出なくなった。

この処理は Ruby から ObjC メソッドを呼び出して、Cocoa のオブジェクトが返ってきたときに行われるんだけど、ほかにもこの処理をしないとならないプロセスがあるんじゃないだろうか。

で、tutorial_1 の件はつかみやすそうなので考えてみよう。

このケースでは、retain されていないのは ib_outlets によって定義されたインスタンス変数だ。このオブジェクトは、nib の初期化処理によって生成され、アウトレットとして Ruby のコントロールクラスに渡される。すると、ObjC 世界から setXXX: の引数として渡されてるわけだ。待てよ、これって ruby 側からのメソッド呼び出しじゃないから、ocm_retain_result_if_necessary() の対象にならないよな。

というわけで、ObjC からの引数として渡すオブジェクトについて対処するようにした。(RBObject.m の diff)