RubyCocoa 今日のコミット 2012-08-26
これ書くのまた久しぶりのような。
@casualconcさんから「NSBundle.loadNibNamed_ownerがLion以降でエラーが出る」との連絡があったので調査して修正。ほんといつもありがとうございます&ご迷惑おかけします。
ついでに全サンプルの動作確認したりとか。今日はがんばった!
- +[NSBundle bundleForClass:]がNSNumberを返すことがあるバグを修正 (r2342)
- 10.8でのパッケージスクリプトの設定 (http://rubycocoa.svn.sourceforge.net/viewvc/rubycocoa?view=revision&revision=2344))
- Xcode 4の環境(10.7以降)ではプロジェクトテンプレートをインストールしないように
- サンプルのHakoiri-Musume(箱入り娘)が起動しなくなってたので修正 (r2345)
- バージョンを1.0.3に設定 (r2347)
後述するリークの問題があったため、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ネイティブに更新
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をリリースします。