|
- Application Kit-
NSTextStorage
Application Kit - NSTextStorage
NSTextStorage とは
Keywords: NSTextStorage, text handling
NSTextStorage ってのは、NSTextView を使ってテキストを取り扱うときに使われるクラスなんだ。主な役目は次の通り:
-
テキストを保持する
NSTextStorage が実際のテキストデータを保持するんだ。このクラスは NSMutableAttributedString を継承してるクラスだから、そっからも分かるよな。
-
NSLayoutManager の参照を保持する
テキスト編集クラスの次の階層である、NSLayoutManager への参照を持っているんだ。複数持つことができるよ。
-
テキストの変更を受け取る、通知する
ユーザが NSTextView に文字を打ち込んだりすると、その編集情報がこのクラスまでやってくるんだ。それを取り扱う。あと delegate にそのイベントを通知したりするんだ。
Application Kit - NSTextStorage
NSTextStorage をプログラムから変更する
Keywords: beginEditing, endEditing
NSTextStorage が保持しているテキストを、プログラムの内部で変更することを考えてみよう。実際には、文字を変更するメソッドが定義されているのは NSTextStorage ではなくて、その親クラスの NSMutableAttributedString だ。NSMutableAttributedString にある、文字変更メソッドや、属性変更のためのメソッドを使うんだ。
1 つ気をつけてほしいのは、beginEditing と endEditing を使うと、もっと効率的に編集が行われる、っていうこと。
Application Kit/NSTextStorage.h
- (void)beginEditing;
- (void)endEditing;
NSTextStorage ではテキストが変更されたら、NSTextLayout を呼んで、NSTextView の画面の表示を変更しないといけない。でも、毎回やってたら遅くなるわな。それをコントロールすることができるんだ。
テキストを変更する前に、beginEditing を呼んでおく。そうすると、その後の変更はとりあえずバッファに突っ込まれて、まだ NSTextLayout に通知されないんだ。変更が終わったら endEditing を呼ぶ。その時点で、NSTextStorage は変更を処理して、上のレイヤに通知するんだ。そこんとこ注意。
Application Kit - NSTextStorage
テキストが編集された通知を受け取る
Keywords: NSTextStorageDelegate
NSTextView を使ってテキストを編集すると、編集の情報が階層を伝って NSTextStorage までやってくるんだ。NSTextStorage はそれをもとに、自分が持っているテキストデータを変更する。そのイベントを delegate が受け取ることができるんだ。
NSTextStorage は、テキストを変更するときに次の 2 つのメッセージを投げる。
Application Kit/NSTextStorage.h
- (void)textStorageWillProcessEditing:(NSNotification *)notification;
- (void)textStorageDidProcessEditing:(NSNotification *)notification;
当然、変更前が textStorageWillProcessEditing: で、後が textStorageDidProcessEditing: だな。これで、テキスト変更のイベントを受け取ることができるぜ。
じゃ、次の質問。どこが変更されたかを知るには?それには NSTextStorage の次のメソッドを使う。
Application Kit/NSTextStorage.h
- (unsigned int)editedMask;
- (NSRange)editedRange;
- (int)changeInLength;
editedMask は、何が変更されたかを調べる。属性か?文字か?その両方か?editedRange は、変更された範囲。changeInLength は何文字が変更されたかだ。文字が挿入されたときはプラスの値。削除されたときはマイナスの値だ。
では、サンプルを見てみよう。
MyDocument.m (sample)
- (void)textStorageDidProcessEditing:(NSNotification*)notification
{
NSTextStorage* textStorage = [_textView textStorage];
unsigned int mask = [textStorage editedMask];
NSRange range = [textStorage editedRange];
int length = [textStorage changeInLength];
if (mask & NSTextStorageEditedAttributes) {
NSLog(@"Edited mask: NSTextStorageEditedAttributes");
}
if (mask & NSTextStorageEditedCharacters) {
NSLog(@"Edited mask: NSTextStorageEditedCharacters");
}
NSLog(@"Edited range: location=%d, length=%d",
range.location, range.length);
NSLog(@"Change in length: %d", length);
}
ここでは textStorageDidProcessEditing: の中で、編集情報を表示させている。プログラムを走らせて、テキストビューに文字を打ち込む度に、このメソッドが呼び出されるのが確認できるはずだよ。
■サンプルダウンロード:
TextStorageDelegate.tar.gz
|