- 2009-11-18 (水) 23:34
- 記事
通勤中にヒレガス本を読んで、帰ってから課題の一つである文字列の入力とその文字数を数えるメッセージを出すというのをやってみた。場所でいうと「5.6 チャレンジ」(日本語版の場合p96、英語はp90)。
まずは素直に IBOutlet/IBAction を使うバージョン。NSTextField の outlet を二つ用意して、ボタンの押下を IBAction のメソッドで受ける。ついでに awakeFromNIB メソッドを定義してラベルの初期値を設定してみた。これは課題のページのすぐ前あたりでやっていることなので簡単。
さらに作りなおしてみる。Key-Value コーディングが面白そうだったので、がらっと違う方法で挑戦。
NSString を二つ(テキスト入力用、テキスト出力用)用意して、@property と @synthesize で setter/getter を自動定義。文字列の入力即文字数カウントとしたかったので、IBで入力テキストフィールドのContinuesを有効にして、setter だけ自前で書く。このへんでどハマり。
まず、NSString の更新ってどうなるんだっけ、と延々マニュアルをあさってみたりする。結局 textField = t; と単純なポインタ代入でよかったようだ。本当はその前にt を retainしたりtextField を release したり必要なはずだが、しばらくはメモリ管理は忘れたままでおきたいので、ガーベージコレクションをビルドオプションでつけて逃げる。
そして、あんのじょう値を直接更新したのに更新通知を飛ばしてしまい、willChangeValueKey と didChangeValueKeyに辿りつくまで長々と悩んでしまう。出力側のテキストの更新も少々悩んだが、こちらは self 経由で [self setLengthMessage:msg]; と @synthesize がつくってくれた setter を指定することで逃げた。
なんだかんだで2,3時間かけて課題完了。少しは勘所がわかってきた気がする。
NIBがないとわからないが、一応二番目の課題でつくったクラス AppController.h。
#import@interface AppController : NSObject { NSString *textField; NSString *lengthMessage; } - (id)setTextField:(NSString *)t; - (int)countLength:(NSString *)t; @property (readwrite, copy) NSString *lengthMessage; @property (readonly) NSString *textField; @end
ついでに AppController.m。
#import "AppController.h"
@implementation AppController
- (id)setTextField:(NSString *)t
{
// set new textField
[self willChangeValueForKey:@"textField"];
textField = t;
[self didChangeValueForKey:@"textField"];
NSLog(@"%@ -> %@", textField, t);
// update length message
[self countLength: t];
return self;
}
- (int)countLength:(NSString *)t
{
NSString *msg;
int length;
// make message from textfield's length
length = textField.length;
msg = [[NSString alloc] initWithFormat:@"'%@' has %d characters.",
textField,
length];
// set value using self-setter(automated)
[self setLengthMessage:msg];
NSLog(@"%@", msg);
return length;
}
@synthesize textField;
@synthesize lengthMessage;
@end
関連記事:
- Newer: PC向け動画配信市場って何だろう
- Older: これはヒレガス本ではない。ヒレガス本++だ。

