(前回)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: でコピーされる理由がわからない。編集に備えて複製しているのだろうか?