きりかノート 3冊め

おあそびプログラミング

RubyCocoa 今日のコミット 2012-08-26

これ書くのまた久しぶりのような。

@casualconcさんから「NSBundle.loadNibNamed_ownerがLion以降でエラーが出る」との連絡があったので調査して修正。ほんといつもありがとうございます&ご迷惑おかけします。

ついでに全サンプルの動作確認したりとか。今日はがんばった!

後述するリークの問題があったため、1.0.3はリリースしないことにしました。

+[NSBundle bundleForClass:]がNSNumberを返すことがあるバグを修正

新しいウインドウを開くときに、NSBundle.loadNibnamed_ownerでnibファイルを読み込みしたりする(ちなみに10.8でobsoleteとありました…)わけですが、LionとMountain Lionでエラーがでてウインドウが開かないとのこと。そのときのメッセージが、

   NSInvalidArgumentException - -[__NSCFNumber pathForResource:ofType:]

で、まあどう見てもNSBundleが来るべきところにNSNumberが来てるよね。$DEBUG = trueでメッセージ調べたりしてもNSNumberがでてこない。どこで生成されてんだろうと思いながら、リファレンスを読み直してみるとownerの説明のところにこんなことが書いてある。

If the class of this object has an associated bundle, that bundle is searched for the specified nib file; otherwise, this method looks in the main bundle.

"associated bundle"があやしい。

RubyCocoa中で定義されたクラスに対して+[NSBundle bundleForClass:]したら、そもそも正しいbundleが返ってくるものなんだろか?と思いつつソースコード読んでたら、RubyCocoaがbundleForClass:をオーバーライドしてることがわかった。まじかよ!

でまあそのあたりにあからさまにバグがあって、RubyCocoaアプリのRubyスクリプト中で定義されたクラスについてbundleForClass:で問い合わせるとNSNumberが返ってきます。これはもう絶対。

というわけで直した。svn blameした限り、犯人はどうも自分のようなんだけど、ぜんぜん記憶にない…

ここからは自分用のメモ。クラスとbundleの対応を保持しているのがNSMutableDictionaryなんだけど、これをRubyのHashにしたほうがいいんじゃないかと試してみた。出し入れでRubyオブジェクトとObjCオブジェクトの変換がひんぱんにあって、Rubyオブジェクトのまま保存するほうが素直だしパフォーマンスも高い(st_table > NSDictionary)はずなんだから。で、試した結果としてはNSProxyがなんたらでうまくいかなかったので、そのままNSMutableDictionaryとした。

サンプルのHakoiri-Musume(箱入り娘)が起動しなくなってたので修正

クラシカルなパズルゲームの箱入り娘のサンプルがあるんだけど、起動しなくなってた。

初期化のメソッドとしてinitというのが定義されてるんだけど、これが引き数を2つとるようになってる。で、RubyCocoaは「NSObject#initと引き数の数がちがうからオーバーライドできんよ」とかゆうわけです。まあわからなくもないのでinitをふつうのinitWith...に名前を変えて直しました。

続いて、1.0.3のタグ打ったあとの修正。

  • samplesのjamベースのプロジェクトをXcodeネイティブに更新 (r2349)
  • config時のオプション--gen-bridge-supportを廃止 (r2350)
  • 10.6で"just leaking"と出る件の対処 (r2351)

samplesのjamベースのプロジェクトをXcodeネイティブに更新

samplesにあるサンプルは、昔のProject Builder(Xcodeの前のMacの開発ツール)形式のターゲットがけっこうあって、それらはXcode 3まではビルドできたんだけど、Xcode 4ではjamはサポートしなくなっていた。Snow Leopard上でXcode 3の「すべてのターゲットをネイティブにアップグレード」を利用して変換した。

これでXcode 4でもサンプルがビルドできるようになってるはず。

10.6で"just leaking"と出る件の対処

以前にXcodeでRubyCocoaプロジェクトを実行すると"invalid option"とログに出力され起動しないの対応をしたところでAutorelease Poolを作成する必要があったみたい。

Snow Leopardでテスト走らせたときに

   __NSAutoreleaseNoPool(: Object ... of class ...
   autoreleased with no pool in place - just leaking

というメッセージが出てたので気がついた。てか、Lion以降だと問題ないのか、それとも単にメッセージを出さなくなっただけなのかがわからんなあ。

たぶん明日1.0.4をリリースします。