4月2010

なぜ Objective-C は気持ち悪いのか – 見た目編

iPhone OS 向けのアプリケーション開発で注目を浴びている Objective-C 言語ですが、Objective-C についてあまりいい噂を耳にしないので、なぜそうなってしまうのかという分析をしてみることにしました。記事が長くなりそうだったので、今回は見た目編です。

1. 見た目

プログラミング言語において、見た目というものは重要な要素のひとつです。Objective-C 言語はオブジェクト指向言語でありますが、実際のコードをみてみると、ほかのメジャーな言語とはちょっと違った構文がとられています。

メッセージ式

Objective-C では、メソッド呼び出しをメッセージ式で記述します。以下は、anObject に message というメッセージを送る例です。

[anObject message];
[anObject message:arg1];
[anObject message:arg1 withObject:arg2];

順に、引数0,1,2個の場合の書き方です。はじめて見られた方はピンとこないかもしれませんので、簡単にメッセージ式の説明をします。Objective-C においてメソッド名は、message の部分にあたります。引数がある場合は、そのあとに : で区切って引数を指定します。

問題は第2引数以降です。Objective-C では、引数にラベルと呼ばれる名前を付けます。したがって、第2引数以降は、”ラベル : 引数” といったように記述します。上の例では、”withObject:arg2″ が第2引数にあたります。

当然疑問は持たれるでしょう。なぜ引数にラベル名と引数の変数名を付ける必要があるのか。特に、ラベル名の意味が気になるかと思われます。Objective-C では、メソッドのオーバーロードが存在しないため、オーバーロードしたい場合には、第2引数以降のラベルによって区別するわけです。ちょうど、上の例のような感じです。また、ラベル名は全く意味のないものではなく、引数の説明の役割を果たしますので、慣れてくるとドキュメントを見なくとも、第2引数以降の意味がわかるようになってきます。

引数ひとつひとつにラベルと呼ばれる名前を付ける Objective-C は、それだけで十分に気持が悪いと言っていいレベルでしょう。最後に、参考までに rangeOfString メソッドの例を載せておきます。

[@"abcdabcdabcd" rangeOfString:@"c" options:NSBackwardsSearch range:NSMakeRange( 4, 9 )];

文字列から特定の文字列を探すメソッドです。この例では、”abcdabcdabcd”という文字列から、”c”という文字列を後ろから検索しますが、検索範囲は4文字目から9文字分の範囲に設定しています。

名前

Objective-C が気持ち悪い理由として、名前を極力省略しないというものも上げることができるのではないでしょうか。例えば、NSString の次のメソッドを見ましょう。

[aString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

これは、文字列をURLエンコードするメソッドです。やや特殊なケースだと思われる方も居られるでしょう。しかし、単に文字列を結合するメソッドは、次のような名前です。

appended = [aString stringByAppendingString:append];

よく使いそうなメソッド名さえ、丁寧な名前の付け方がなされています。

引数のラベル名との相乗効果で、よりいっそうコード量が増えそうです。

次は、クラス定義の気持ち悪さについて語ります。

libavcodec / libavformat を使ってみる 1

ちょっと特殊なエンコード処理をしてみたい気分だったので、ffmpegを参考に、libavcodec, libavformat あたりを使ってみることにしました。

とりあえず今日は、動画ファイルのコーデック名を出力するようなプログラムを組んでみました。

Mac OS X で開発した場合は、MacPortsで ffmpeg をインストールし、XCodeの新規プロジェクトで Command Line Tool C で作成します。そのあと、プロジェクトの設定のビルドのタブで、ヘッダ検索パスに Ports でインストールしたヘッダなどが含まれる /opt/local/inculude あたりを設定し、プロジェクトに libavcodec.a と libavformat.a を加えるとビルドできるようなるはずです。

まず、ヘッダをインクルードします。libavcodec, libavformat は、次のヘッダをインクルードすると使えます。

#include <avcodec.h>
#include <avformat.h>

libavcodec, libavformat を使うプログラムでは、最初に av_register_all() を呼び出して、初期化します。

av_register_all();

今回は、ファイルの情報を調べたいので、av_open_input_file() を使って、ファイルの情報を得ます。この関数で得た AVFormatContext 構造体に、たくさんの情報が入ります。ここで得た AVFormatContext は、不要になったら av_close_input_file() で解放する必要があります。必要な引数は第二引数までで、動画のフォーマットを強制したい場合などに以降の引数は使用します。今回は自動判別して欲しいので、第三引数からは何も指定しません。

AVFormatContext *format;
if ( av_open_input_file( &format, filename, NULL, 0, NULL ) ) {
	puts( "Couldn't open file" );
}

次に、 av_find_stream_info() を使ってストリームの情報を付加します。

if ( av_find_stream_info( format ) < 0 ) {
		puts( "Couldn't find stream information" );
		return -1;
	}

ストリームの情報も得られたところで、各々のストリームのコーデックを出力します。

for ( int i = 0; i < format->nb_streams; i++ ) {
	printf( "stream #%dn", i );
	printf( "tcodec type: %dn", format->streams[i]->codec->codec_type );

	enum CodecID codec_id = format->streams[i]->codec->codec_id;
	AVCodec *codec = avcodec_find_decoder( codec_id );
	if ( codec ) {
		printf("tcodec name: %sn", codec->name );
	} else {
		printf( "tcodec id %d is not foundn", codec_id );
	}
}

format->nb_streams にストリーム数が書かれているので、その分だけ情報を出力します。 各ストリームの情報は、format->streams に入っています。AVStream 構造体の配列になっています。そしてその中の codec がコーデックの情報を表わしており、それは AVCodecContext 構造体です。この中のコーデックIDを得ることにより、IDから avcodec_find_decoder() を用いてデコーダを得ることができます。デコーダには、そのデコーダのコーデックの情報が入っていて、そのコーデックの名前も得ることができます。こうして、デコーダからコーデック名を得ることができるわけです。

このあとに、上で得たデコーダのコンテキストから、実際のデコーダを生成すれば、ストリームをデコードすることができるわけです。

サンプルソース: main.c

参考文献:
http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html
svn://svn.ffmpeg.org/ffmpeg/trunk ffmpeg

テーマファイルを作成してみた

ブログを全く更新してないなかったので、ちょっと前の話題なのですが、せっかく WordPress レッスンブックを買ったので、テーマファイルを作ってみました。この本の通りにやっていけば、簡単にテーマを作成できます。

WordPressレッスンブック 2.8対応―ステップバイステップ形式でマスターできる WordPressレッスンブック 2.8対応―ステップバイステップ形式でマスターできる

ソシム 2009-09
売り上げランキング : 4808

Amazonで詳しく見る by G-Tools

本にはありませんが、ウィジェットへ対応させるのも非常に簡単なので、テーマを作成した人は、ついでにウィジェットにも対応させるといい感じです。ものの数分で対応できると思います。発見した注意点としては、この本のサンプルには、wp_header() と wp_footer() 関数が使われていなかったので、これをヘッダとフッタ部に挿入するようにしましょう。この関数がないと、プラグインが正常に動作しないことがあります。

まだ画像の表示が乱れたり、プラグインの方を試験中で表示に乱れがあることがありますが、いづれ改善したいです。