3月2009

予測変換を活用してみる 2

前回のエントリの続きです。

前回は、3文字以上入力しているときに、入力中の文字よりも2文字以上多い候補をひとつだけ表示する予測変換を作ってみたわけですが、よくよく考えてみれば、日本語はひらがなよりも漢字の方が字数が少ないこともあるので、この候補の表示の仕方は、あまり役に立たない気がしてきました。

というわけで、思い切って予測変換の第一候補だけ表示みることにしてみました。

予測変換

やはり、予測変換というものは、キーボードを打ち慣れていない人だけの機能なのでしょうか。候補を見ているなら、打ってしまった方が明らかに速いでしょう。

しかも、予測変換とは、割と思考の妨げになるものです。自分の思考と違う文章が候補に表示されるほど、文章を書くときに邪魔になることはありません。

予測変換を活用してみる

最近 Social IME の話題ばかりで、他の記事を期待している方には申し訳ないです。

Social IME では、予測変換の API も用意されていますが、予測変換というものは、すでにキーボード入力に慣れてしまった人には、煩わしいものかと思います。Mac版クライアントの Social IM に予測変換機能をまだ追加していないのは、そのためです。どうにかして、すでに入力に慣れているユーザーにも予測変換を活用できるようにしようと思い、漢字変換に部分的に予測変換を組み込んでみました。

ヒントは「ことえり」です。ことえりには、「最近使った単語」を Tabキー で入力できる機能があり、それを真似して、予測変換を取り入れてみようかと考えました。

最初の数文字で予測が出るのは邪魔なので、3文字くらいから出すようにし、さらに、入力中の文字数よりも2文字以上多い候補を一つだけ出すようにしてみました。

部分予測

実装してみて、今実際に使っているのですが、あまり役立ちそうにありません。ここまで文章を打って、「キーボード」という単語を入力するときに、多少楽になった程度です。もともと、ことえりの最近使った単語機能も、地味な機能だったので、こんなものなのかと。

メモリリークを調査する

Mac OS X の話です。

アプリケーションを作ったら、一度はメモリリークを調査しておきたいものです。そんなときは、leaks コマンドと Instruments を使って調査しましょう。leaks コマンドは、引数にプロセスIDを与えることで、そのプロセスのメモリリークの状況を表示してくれます。ここでリークが0であれば、全く問題ないので、ここで調査は終了です。

プロセスIDは、アクティビティモニタやpsコマンドで調べることができます。

実行結果:メモリリークがないとき

Process 171: 31663 nodes malloced for 2375 KB
Process 171: 0 leaks for 0 total leaked bytes.

もし leaks コマンドでリークが見つかった場合は、さらに詳細な状況を Instruments を使って調べることができます。

Instruments では、さまざまなものをモニターすることができます。メモリリークでは、Leaksのテンプレートを使用しましょう。

Instruments templates

モニターは、アプリケーションを指定して、録画っぽいボタンを押すと始まります。モニターが始まると、上にグラフと、下に詳細なデータが表示され、どのタイミングでリークが起こっているのか、詳しく調べることが出来ます。

Instruments templates

このように、リークの調査は比較的簡単に行えるので、アプリケーションを公開する前には、leaksコマンドくらいは使っておきたいものです。

NSDictionary で使用できないキー

NSDictionary のキーには、どんな文字列も入れていいように思えますが、実は使用できない文字列があります。それは、「@」から始まる文字列です。

どうして使用できないのかといえば、「@」から始まる文字列は、キー値コーディングの記法と衝突するからです。Cocoa では、valueForKey: でアクセサメソッドを呼び出すこともできますが、それ以外に、@で始まる配列演算子というものがあります。

次のコードを見てみましょう。NSArray に NSDictionary を詰める、よくテーブルとかで使いたくなるデータ構造です。

NSMutableArray *array = [NSMutableArray array];
NSNumber *number;
NSDictionary *dict;
for ( int i = 0; i < 5; i++ ) {
	number = [NSNumber numberWithInt:i];
	dict = [NSDictionary dictionaryWithObject:number forKey:@"number"];
	[array addObject:dict];
}

NSLog(@"count %d", [[array valueForKey:@"@count"] intValue]);

NSLog(@"count %d", [[array valueForKeyPath:@"number.@count"] intValue]);
NSLog(@"sum %d", [[array valueForKeyPath:@"@sum.number"] intValue]);
NSLog(@"max %d", [[array valueForKeyPath:@"@max.number"] intValue]);
NSLog(@"min %d", [[array valueForKeyPath:@"@min.number"] intValue]);
NSLog(@"avg %f", [[array valueForKeyPath:@"@avg.number"] floatValue]);

コードを見ての通り、このような配列演算子をキーパスに含めることによって、簡単な演算をすることが出来ます。

なぜこんなものが用意されているのでしょうか?それは Cocoa バインディング を使用したときにわかります。Interface Builder 上でバインドするとき、当然この配列演算子を使うことも出来るわけです。つまり、テーブルに配列をバインドしたときに、要素の合計が欲しかったりしたときに、@sum を使って、NSTextField あたりにバインドすれば、コードを書くことなく、要素の合計を表示することが出来ます。

今回、この配列演算子の存在をすっかりと忘れていたために、Social IM にバグがありました。それは「@」が入力できないバグです。「@」を入力されたとき、「@」をNSDictionary のキーに渡していたのですが、valueForUndefinedKey が 呼ばれるどころか、例外も発生してしまって、そこで処理が中断してしまったのです。

というわけで、なんでもかんでも NSDictionary のキーに文字列が入ると思っていた方は注意してください。

キー値コーディング 配列演算子 (ADC 日本語訳)