2016-07-28 97 views
0

我想向NSTableViewDataSource协议添加一个默认方法。但是当我这样做时,即使在实际数据源中定义了方法时,也总是调用默认值。具体来说:用默认方法扩展NSTableViewDataSource协议

我有一个单列NSTableView可以在不同时间采用几个不同的数据源。在一种情况下,我希望数据源能够提供不仅显示的值,而且还提供表中行的背景颜色。在其他情况下,表格可以是单一颜色。我的想法是第一延长NSTableViewDataSource协议:

extension NSTableViewDataSource 
    { 
    func tableView (tableView: NSTableView, colorIndexForRow row: Int) -> Int 
     { 
     return 0 
     } 
    } 

然后在表委托我把这个:

public func tableView (tableView: NSTableView, didAddRowView rowView: NSTableRowView, forRow row: Int) 
    { 
    let colorIndex = tableView.dataSource()!.tableView(tableView, colorIndexForRow: row) 
    rowView.backgroundColor = rowColors[colorIndex] 
    } 

(rowColors只是NSColor对象,六用于实验目的的阵列。)

最后,我的实验数据来源是这样的:

public func numberOfRowsInTableView (tableView: NSTableView) -> Int 
    { 
    return 100 
    } 

public func tableView (tableView: NSTableView, objectValueForTableColumn column: NSTableColumn?, row: Int) -> AnyObject? 
    { 
    return String(format: "This is row %3i", row) 
    } 

public func tableView (tableView: NSTableView, colorIndexForRow row: Int) -> Int 
    { 
    return row % 6  
    } 

我预计这会产生一个表格,其中的行是六种颜色的旋转循环。我实际上得到的是一个全部用rowColors [0]的颜色表格。我的colorIndexForRow方法的默认值始终被调用,即使我在数据源中提供了该方法。我对Swift文档的看法是,只有当实际方法不存在时,才会调用协议扩展中的默认值。谁能告诉我我做错了什么?

回答

1

原因是因为协议扩展doesn't support class polymorphism

你可以重写你的函数为:

public func tableView (tableView: NSTableView, didAddRowView rowView: NSTableRowView, forRow row: Int) 
{ 
    let colorIndex = self.tableView(tableView, colorIndexForRow: row) 
    rowView.backgroundColor = rowColors[colorIndex] 
} 
+0

嗯......哇?我想你已经回答了我的问题,但请给我一两天的时间来吸收你提供的参考。与此同时,我还没有能够使你的建议功能工作,可能是因为我没有强调,如果可能的话,我想保持表代表独立于数据源。这个函数在委托中,并且self.tableView在那里不可用。我会考虑重新安排事情,但现在我不确定扩展协议是最好的方法。 –

+0

非多态意味着当你定义一个函数时,你必须坚持这个原始定义。为tableView(,colorForRowIndex:)提供新实现的类不能替代它。这就是为什么它总是返回0 - 这就是它原来的定义。 –

+0

感谢您的帮助。我已经发布了一个似乎对我有用的最终答案,但我已经给了你一面绿旗,并有权投票让我走上正轨。我希望这都符合StackOverflow协议。 –

0

我已经决定采取不同的策略:我简单的一个功能需求没有理由处理静态VS动态调度的问题。不是扩展NSTableViewDataSource的,我定义了一个继承的协议:

public protocol  ColorTableViewDataSource: NSTableViewDataSource 
    { 
    func tableView (tableView: NSTableView, colorIndexForRow row: Int) -> Int 
    } 

然后对符合我的委托功能检查:

public func tableView (tableView: NSTableView, didAddRowView rowView: NSTableRowView, forRow row: Int) 
    { 
    if let dataSource = tableView.dataSource() as? ColorTableViewDataSource 
     { 
     rowView.backgroundColor = rowColors[dataSource.tableView(tableView, colorIndexForRow: row)] 
     } 
    } 

我的数据源功能不会改变的。当我想要彩色行时,我只是声明数据源对象符合新协议。它似乎正是我想要的。