2013-01-20 63 views
1

我必須添加一個源列表(àla iTunes)到我的Mac應用程序。爲此,我嘗試(SidebarDemo from Apple)。它工作正常。我在此演示中添加了一個按鈕,以演示reloadData方法對NSOutlineView的影響。正如你在圖像中看到的那樣,在reloadData呼叫之前,在左邊,在reloadData之後,在右邊,有一個問題。徽章消失,圖標變化等。奇怪的行爲與蘋果SidebarDemo

問題是什麼?我是否應該避免在NSOutlineView上使用reloadData

我使用OS X 10.8.2,SDK 10.8和Xcode 4.5.2。

您可以下載修改後的SidebareDemo項目here

謝謝!

Before and after...

回答

1

的SidebarDemo代碼使得使用相同的對象,以表示大綱視圖多個行的錯誤。特別地,由數據源所使用的基礎數據被創建像這樣:

_childrenDictionary = [NSMutableDictionary new]; 
[_childrenDictionary setObject:[NSArray arrayWithObjects:@"ContentView1", @"ContentView2", @"ContentView3", nil] forKey:@"Favorites"]; 
[_childrenDictionary setObject:[NSArray arrayWithObjects:@"ContentView1", @"ContentView2", @"ContentView3", nil] forKey:@"Content Views"]; 
[_childrenDictionary setObject:[NSArray arrayWithObjects:@"ContentView2", nil] forKey:@"Mailboxes"]; 
[_childrenDictionary setObject:[NSArray arrayWithObjects:@"ContentView1", @"ContentView1", @"ContentView1", @"ContentView1", @"ContentView2", nil] forKey:@"A Fourth Group"]; 

相同值的的NSString文字是由編譯器uniqued,所以@"ContentView1"每次出現時是指相同的對象在內存中。這樣做的結果是,當-outlineView:viewForTableColumn:item:內的代碼查找項目的父項以確定要使用哪個圖標或未讀狀態時,-[NSOutlineView parentForItem:]將永遠只返回所有@"ContentView1"項目的單個父項。在最初的情況下它完全有效的事實似乎是實施中的一個事故。在初始加載與重新加載期間,對-outlineView:viewForTableColumn:item:的調用順序稍有不同。

解決方法是使用唯一的對象來表示大綱視圖中的每個項目。最微不足道的改進形式,可實現此SidebarDemo樣品存放在_childrenDictionary之前創建的每個NSString的值的可變副本:

_childrenDictionary = [NSMutableDictionary new]; 
[_childrenDictionary setObject:[NSArray arrayWithObjects:[@"ContentView1" mutableCopy], [@"ContentView2" mutableCopy], [@"ContentView3" mutableCopy], nil] forKey:@"Favorites"]; 
[_childrenDictionary setObject:[NSArray arrayWithObjects:[@"ContentView1" mutableCopy], [@"ContentView2" mutableCopy], [@"ContentView3" mutableCopy], nil] forKey:@"Content Views"]; 
[_childrenDictionary setObject:[NSArray arrayWithObjects:[@"ContentView2" mutableCopy], nil] forKey:@"Mailboxes"]; 
[_childrenDictionary setObject:[NSArray arrayWithObjects:[@"ContentView1" mutableCopy], [@"ContentView1" mutableCopy], [@"ContentView1" mutableCopy], [@"ContentView1" mutableCopy], [@"ContentView2" mutableCopy], nil] forKey:@"A Fourth Group"]; 

在現實世界中的代碼你是不可能的,因爲要由這個問題咬傷您的基礎數據對象將由模型類的實例組成,而不僅僅由字符串文字組成。

+0

謝謝bdash! – Olof