1

我正在处理可可中基于视图的 TableView。在 tableview 数据源方法中,我想根据它们相关的对象类型创建三个不同的单元格。
我的想法是在 if 语句之前为单元格创建一个通用 id 变量,然后在我对与之相关的对象进行自省时将其转换为 if 内的正确单元格类型。不幸的是,使用这种方法,xcode 抱怨通用单元格变量没有我尝试在里面设置的属性。它无法识别我在上一行中所做的投射。

我知道这是一个非常基本的问题,但是在objective-c/cocoa 中解决这个问题的常用模式是什么。

下面是数据源方法的代码:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row 
{
    GeneralVector *vector = [self.vectors objectAtIndex:row];
    id cellView;
    if ([[self.vectors objectAtIndex:row] isKindOfClass:[Vector class]]) {
        cellView = (VectorTableCellView *)[tableView makeViewWithIdentifier:@"vectorCell" owner:self];
        cellView.nameTextField.stringValue = vector.name;
    } else if ([[self.vectors objectAtIndex:row] isKindOfClass:[NoiseVector class]]) {
        cellView = (NoiseVectorTableCellView *)[tableView makeViewWithIdentifier:@"noiseVectorCell" owner:self];
    } else {
        cellView = (ComputedVectorTableCellView *)[tableView makeViewWithIdentifier:@"computedVectorCell" owner:self];
    }

    return cellView;
}    
4

2 回答 2

3

您不必强制执行分配,因为所有内容都按定义是idObjective-C 的后代。相反,您需要在取消引用该属性的位置进行转换。所以,改变你的代码看起来更像这样:

if( /* some check */ ) {
  // No need to cast here, we are all descended from 'id'
  cellView = [tableView makeViewWithIdentifier:@"vectorCell" owner:self];
  // Here, we need to cast because we need to tell the compiler how to format
  // the method call for the 'nameTextField' property, so it needs to know
  // some information about the class
  ((VectorTableCellView*)cellView).nameTextField.stringValue = vector.name;
} else if( /* some other check... */ {
  // and so on
}
于 2012-07-04T05:59:23.277 回答
-1

如果 VectorTableCellView 、 NoiseVectorTableCellView 是从 NSView 继承的,则使用“NSView *cellView”代替“id cellView”。

如下

  • (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row

{

    GeneralVector *vector = [self.vectors objectAtIndex:row];
    NSView *cellView;
    if ([[self.vectors objectAtIndex:row] isKindOfClass:[Vector class]]) 
    {

        cellView = (VectorTableCellView *)[tableView makeViewWithIdentifier:@"vectorCell" owner:self];

        cellView.nameTextField.stringValue = vector.name;

    } 

    else if ([[self.vectors objectAtIndex:row] isKindOfClass:[NoiseVector class]]) 
    {

        cellView = (NoiseVectorTableCellView *)[tableView 
         makeViewWithIdentifier:@"noiseVectorCell" owner:self];

    } 
    else 
    {

        cellView = (ComputedVectorTableCellView *)[tableView 
        makeViewWithIdentifier:@"computedVectorCell" owner:self];

    }

    return cellView; }
于 2012-07-04T05:53:27.363 回答