用默认方法扩展NSTableViewDataSource协议
问题描述:
我想向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文档的看法是,只有当实际方法不存在时,才会调用协议扩展中的默认值。谁能告诉我我做错了什么?
答
原因是因为协议扩展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]
}
答
我已经决定采取不同的策略:我简单的一个功能需求没有理由处理静态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)]
}
}
我的数据源功能不会改变的。当我想要彩色行时,我只是声明数据源对象符合新协议。它似乎正是我想要的。
嗯......哇?我想你已经回答了我的问题,但请给我一两天的时间来吸收你提供的参考。与此同时,我还没有能够使你的建议功能工作,可能是因为我没有强调,如果可能的话,我想保持表代表独立于数据源。这个函数在委托中,并且self.tableView在那里不可用。我会考虑重新安排事情,但现在我不确定扩展协议是最好的方法。 –
非多态意味着当你定义一个函数时,你必须坚持这个原始定义。为tableView(,colorForRowIndex:)提供新实现的类不能替代它。这就是为什么它总是返回0 - 这就是它原来的定义。 –
感谢您的帮助。我已经发布了一个似乎对我有用的最终答案,但我已经给了你一面绿旗,并有权投票让我走上正轨。我希望这都符合StackOverflow协议。 –