ページ

2009年11月27日金曜日

NSTableView にカスタムビューを表示する (4) カスタムセル続き

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

(前回)Cocoaの日々: Cocoaの日々: NSTableView にカスタムビューを表示する(3) カスタムセルの作成

setDataCell:
前回のコメントで -[NSTableColumn setDataCell:] を使わないのかと指摘を受けた。

Mac Dev Center: NSTableColumn Class Reference

どちらかといえばこちらが正攻法か。試してみよう。


@interface TableViewController : NSObject {
 :
IBOutlet NSTableColumn* tableColumn;
}


NSTableColumn のアウトレットを用意しておき、InterfaceBuilder で接続しておく。


-(void)awakeFromNib
{
CustomCell* cell = [[[CustomCell alloc] init] autorelease];
[cell setEditable:NO];
[tableColumn setDataCell:cell];
}


起動時にそこへ CustomCell のインスタンスを渡してやる。

実行。

前回と同じ挙動。なお前回と違って CutomCell を NSTextfiledCell のサブクラスとしてDBの値を表示させている。

試しに copyWithZone: を実装してみた。

CutomCell.m

- (id)copyWithZone:(NSZone *)zone
{
NSLog(@"self=%@, copyWithZone:%@", self, zone);
CustomCell* cell = (CustomCell*)[super copyWithZone:zone];
return cell;
}


実行時の挙動を見ていると copyWithZone: はセルが選択された時だけ呼び出された。

CustomCell[4469:10b] self=<CustomCell: 0x13db50>, copyWithZone:(null)

self は最初に NSTableColumn へセットした CustomeCell のインスタンスを常に指す。コピーして使い回しているのがわかる。ただセルを選択しない限りは copyWithZone: は呼ばれない。ということは表示だけの時は CustomeCell インスタンス一つを使い回しているということか。

試しに描画メソッドに値を書き出してみる。

CustomCell.m

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
[[NSColor greenColor] set];
NSRectFill(cellFrame);
[super drawWithFrame:cellFrame inView:controlView];

NSLog(@"self=%@, value=%@", self, [self stringValue]);
}


CustomCell[4488:10b] self=<CustomCell: 0x13db50>, value=SAMPLE-0
CustomCell[4488:10b] self=<CustomCell: 0x13db50>, value=SAMPLE-1
CustomCell[4488:10b] self=<CustomCell: 0x13db50>, value=SAMPLE-2

CustomCellのインスタンスは一つで、値だけが変わっている。
おーそういうことか。NSCellのインスタンス は NSTableColumn 内で使い回されるのか。

セルが選択された時に copyWithZone: でコピーされる理由がわからない。編集に備えて複製しているのだろうか?