我必须在Mac应用程序中添加源列表(如iTunes)。为此,我尝试了(SidebarDemo from Apple)。它工作正常。我在此演示中添加了一个按钮,以演示reloadData方法对NSOutlineView的影响。正如您在图像中看到的那样,这是有问题的(在左侧,在reloadData调用之前,在右侧,在reloadData调用之后)。徽章消失,图标更改,等等。

问题是什么?我应该避免在reloadData上使用NSOutlineView吗?

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

您可以下载修改后的SidebareDemo项目here

谢谢!

最佳答案

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文字由编译器唯一,因此,每次出现的@"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"];


在现实世界的代码中,您不太可能被该问题所困扰,因为基础数据对象将由模型类的实例组成,而不是仅由字符串文字组成。

关于macos - Apple SidebarDemo的奇怪行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14425936/

10-10 22:29