0

を使用して UI 要素を作成しようとしていますNSBrowserが、何らかの理由で、ブラウザーの各セルに対して新しいセル インスタンスを作成するのではなく、指定したカスタム セル クラスのシングルトン インスタンスをブラウザーが作成します。特に、デリゲートの実装は次のとおりです

- (void)awakeFromNib {
    [super awakeFromNib];

    self.browser.target = self;
    self.browser.doubleAction = @selector(_doubleClick:);
    self.browser.reusesColumns = YES;
//    self.browser.cellClass = [CLColumnViewCell class];
    [self.browser setCellPrototype:[[CLColumnViewCell alloc] init]];
}

#pragma mark NSBrowserDelegate

- (void)browser:(NSBrowser *)browser createRowsForColumn:(NSInteger)column inMatrix:(NSMatrix *)matrix {
    NSLog(@"This method never gets called");
}

- (NSInteger)browser:(NSBrowser *)browser numberOfChildrenOfItem:(id)item {
    return [(item ?: _root) countOfContents];
}

- (BOOL)browser:(NSBrowser *)browser isLeafItem:(id)item {
    return ![(item ?: _root) canHaveContents];
}

- (id)browser:(NSBrowser *)browser child:(NSInteger)index ofItem:(id)item {
    return [(item ?: _root) objectInContentsAtIndex:index];
}

- (id)browser:(NSBrowser *)browser objectValueForItem:(id)item {
    return nil; // Object value is handled by CLColumnViewCell itself.
}

- (void)browser:(NSBrowser *)browser willDisplayCell:(CLColumnViewCell *)cell atRow:(NSInteger)row column:(NSInteger)column {
    NSIndexPath *indexPath = [[browser indexPathForColumn:column] indexPathByAddingIndex:row];
    cell.columnView = browser;
    cell.indexPath = indexPath;
    cell.object = [browser itemAtIndexPath:indexPath];
    NSLog(@"will display cell %@", cell, cell);
}

ログメッセージは次のようになります

2012-11-11 09:57:16.582 will diplay cell <CLColumnViewCell: 0x102e597c0>
2012-11-11 09:57:16.583 will diplay cell <CLColumnViewCell: 0x102e597c0>
2012-11-11 09:57:16.583 will diplay cell <CLColumnViewCell: 0x102e597c0>
2012-11-11 09:57:16.584 will diplay cell <CLColumnViewCell: 0x102e597c0>
2012-11-11 09:57:16.584 will diplay cell <CLColumnViewCell: 0x102e597c0>
2012-11-11 09:57:16.585 will diplay cell <CLColumnViewCell: 0x102e597c0>
2012-11-11 09:57:16.585 will diplay cell <CLColumnViewCell: 0x102e597c0>
2012-11-11 09:57:16.586 will diplay cell <CLColumnViewCell: 0x102e597c0>
2012-11-11 09:57:16.587 will diplay cell <CLColumnViewCell: 0x102e597c0>
2012-11-11 09:57:16.587 will diplay cell <CLColumnViewCell: 0x102e597c0>
2012-11-11 09:57:16.588 will diplay cell <CLColumnViewCell: 0x102e597c0>
2012-11-11 09:57:16.588 will diplay cell <CLColumnViewCell: 0x102e597c0>
2012-11-11 09:57:16.589 will diplay cell <CLColumnViewCell: 0x102e597c0>
2012-11-11 09:57:16.589 will diplay cell <CLColumnViewCell: 0x102e597c0>

メッセージが示すように、同じセル インスタンスが何度も使用されます。NSBrowser同じインスタンスを再利用するのではなく、強制的に新しいセル インスタンスを作成する方法はありますか?

4

1 に答える 1

1

あまり。結局のところ、これがNSCellの要点です。NSCellは、NSViewの軽量な代替手段です。これは、パフォーマンスが制限されていた時代において、より重要でした。確かに、Appleは、NSTableViewやNSOutlineViewなどの以前はセルが多かったコントロールに対してNSViewベースの代替手段を作り始めました。彼らはNSViewベースのNSBrowserを実行することに慣れていないと思います。(NSTableView APIを見ても、その理由は簡単にわかります。改造はちょっと不格好です。最初からやり直したほうがよかったかもしれませんが、私は逸脱します...)

つまり、NSCellの全体的な考え方は、毎回新しいオブジェクトを再割り当てするのではなく、再利用できる軽量のオブジェクトを用意することであるため、毎回新しいオブジェクトを作成する簡単な方法があったとしたら、私は驚きます。時間。NSBrowserをサブクラス化することでこの動作をハックできるかもしれませんが、別のアプローチを考え出す方がおそらく良いでしょう。

于 2013-02-13T00:04:31.837 に答える