1月2011

ffmpegの再配布について

以前、nConverterというソフトを作ってとりあえずリリースしましたが、その後、自分が使わないので放置し続けていて、OS X 10.6 でうまく動作しない状態でした。

最近なんとなく気が向いたので、うまく動かない部分を修正していっているのですが、主な修正箇所は NSCollectionView がうまく表示されないという謎な箇所でした。ログに unlockfocusなんとか と出るだけで、かなり謎でしたが、NSCollectionViewItem の View に乗っている NSImageView の中の NSProgressIndicator が原因でした。結局何をしても NSProgressIndicator が邪魔するようだったので、あまり必要もないので削除して対処しました。

ついでに動画の変換もうまくいかなかったので、原因を調査していると、どうやらmovtowavに変なバグがあって、どうしてもうまく動きませんでした。movtowavを配っていたサイトもなくなってしまったので、ffmpegのみでエンコードできないかと試すと、最新のffmpegなら十分エンコードできそうでした。(以前のffmpegはffmpegXのffmpegを使っていました)

そこで、ffmpegのみでエンコードできるように改良して、とりあえず修正は完了したのですが、ここで大きな問題が発生しました。

iPhone用の動画はmp4でh264/AACなのですが、この音声コーデックのAACエンコーダであるlibfaacを付けてffmpegをビルドすると、ライセンス上 ffmpeg を再配布できなくなってしまい、nConverterに同梱できなくなってしまうのです。

ffmpegはユーザーにビルドしてもらうという手もありますが、それはなかなか敷居が高く、しかもバージョンによってオプションの指定が変わったりもするので、そうするのは難しいです。

そんなわけで、せっかく修正したものを、どうやってリリースしようか迷っています。

なぜ iPhone プログラミングではデリゲートを多用するのか

iOS / iPhone プログラミングでは、デリゲートをよく見かけることになります。どうしてこんなに見かける羽目になってしまったのでしょうか。それを考えてみることにします。

まず1つ。iPhone アプリケーションでもっとも基本的なユーザーインターフェースは、おそらくテーブルビュー ( UITableView )になるのではないでしょうか。このテーブルビューの実装では、少なくとも2つのデリゲートを実装することになります。それは、UITableViewDataSource と UITableViewDelegate であり、1つのクラスで両方のデリゲートを実装してしまえば、1つのクラスしかできませんが、それでもテーブルビュー1つにつき、2つのデリゲートを実装する必要があるのです。

そして2つ目。アプリケーションにも依りますが、 NSURLConnection ではデリゲートで通信のやりとりをします。つまり、ネットワークから何かリソースを取得するようなプログラムの場合、この NSURLConnection によってデリゲートを使う必要が出てくるわけです。

他にも UIAlert など、デリゲートが出てくる場面はたくさんあります。その結果、iOS / iPhone プログラミングでは、デリゲートを多用する必要が出てきてしまっているのでしょう。

一方で、OS X はどうなっているのかと言えば、そもそも UI の基本がテーブルビューとは限らないので、iOS ほどテーブルビューを使いません。そして何よりも、 OS X では Cocoa Biding が利用できるわけで、outlet / action 接続がほとんど無くなるだけでなく、テーブルビューでデータソースをデリゲートにする必要もなくなり、デリゲートの数が少なくなります。

iOS / iPhone で Cocoa Binding が無いのは、おそらくオーバーヘッドが大きいし、バインドして値を同期させるほどの処理性能が iPhone にはないからだと考えておりますが、よりデバイスが進化した数年後には、Cocoa Binding が iPhone でも使えるようになっていてもおかしくはないと思います。

Objective-C の名前空間について

Objective-C には名前空間がありません。そのことについて、不満を述べるプログラマが少なからず居るようですが、私はそんなことは思いません。なぜなら、名前空間は便利こそあれど、本質的にプログラミングに関係することではないと思っているからです。

Objective-C のランタイムシステムや Cocoa フレームワークの名前は、衝突を防ぐために古典的な方法がとられているのは、すぐにわかると思います。それは、名前の前に接頭辞を付けることです。たとえば、NSObject であったら、NS の部分がそれにあたります。

もし名前空間の機能があれば、おそらくファイルの先頭で名前空間の使用を宣言すれば、それ以降に接頭辞を付けることなくクラス名を書くことができるでしょう。これによって、記述が少なくなり、打つ手間も省けるでしょう。ただし、Objective-C の命名規則では、先頭の二文字が省略できるにすぎませんが。要するに、名前空間があったとしても、それほど便利になるとは思えないというところです。Objective-C は、Cから比較的簡素な拡張のされ方をしている言語なので、極力言語に機能を追加しないほうがいいと、私は考えています。

そうは言うものの、無いものは不便と感じる方も居ますので、気休め程度に名前空間が無いメリットを紹介します。

それは、クラス名がユニークなので、とても検索しやすいことです。クラス名が String であったら、検索したときにほかの言語の情報が出てくるかもしれませんが、 NSString ならば、簡単に NSString の情報を探し出すことができます。ついでに言うと、Objective-C の長いメソッド名も、打つのは大変であれど、検索しやすくていいところもあります。逆に検索結果が少なすぎて絶望することもありますが。

このように、名前空間が無いからこそのメリットもありますので、そんなに悲観すべきことではないと思います。

今年はもっと記事書けるように頑張ります

新年、12月は記事を1エントリーも書かずに、ついに明けてしまいました。残念です。ここ最近、ブログの更新をサボっている感じになっていますので、月5エントリーペースで書きたいですね。

Objective-C のクイックリファレンスの方も、更新が途絶えてますが、今続きを書き始めているので、近日中に増えると思います。しかし、数ヶ月前から Interface Builder の記事を書きたくて仕方ないので、そちらを先に書き始めてしまうかもしれませんが。本当は、新しいXcodeが出てから書きたいのですが、なかなか出そうにないので、先に書いてしまう予定です。

Interface Builder に関する記事はとても少ない印象で、そして使っていない方が、もしかすると多数派なのかもしれないので、Inteface Builder のすばらしさを伝えられる記事にしたいです。