1

我必须在我的 Mac 应用程序中添加一个源列表(à la iTunes)。为此,我尝试了(Apple 的 SidebarDemo)。它工作正常。我在这个演示中添加了一个按钮来演示该reloadData方法在NSOutlineView. 正如您在图像中看到的那样,存在问题(左侧,reloadData通话前,右侧,reloadData通话后)。徽章消失,图标改变等。

问题是什么?我应该避免使用reloadDataonNSOutlineView吗?

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

您可以在此处下载修改后的 SidebareDemo 项目。

谢谢!

之前和之后...

4

1 回答 1

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 字面量由编译器唯一标识,因此每次出现的 都@"ContentView1"指向内存中的同一个对象。这样做的结果是,当内部代码-outlineView:viewForTableColumn:item:查找项目的父项以确定要使用哪个图标或未读状态时,-[NSOutlineView parentForItem:]将只返回所有项目的单个父@"ContentView1"项。它在最初的情况下完全有效的事实似乎是实施中的意外。-outlineView:viewForTableColumn:item:在初始加载和重新加载期间,调用的顺序略有不同。

解决方案是使用独特的对象来表示大纲视图中的每个项目。实现此目的对 SidebarDemo 示例最简单的修改是在将每个 NSString 值存储到之前创建一个可变副本_childrenDictionary

_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"];

在实际代码中,您不太可能被此问题困扰,因为您的底层数据对象将由模型类的实例组成,而不是仅由字符串文字组成。

于 2013-01-20T22:43:03.607 回答