2016-07-28 128 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)] 
     } 
    } 

我的數據源功能不會改變的。當我想要彩色行時,我只是聲明數據源對象符合新協議。它似乎正是我想要的。