2013-01-20 2 views
1

Mac 응용 프로그램에 소스 목록 (iTunes 용)을 추가해야합니다. 이를 위해 나는 (SidebarDemo from Apple)을 시도한다. 그것은 잘 작동합니다. 이 데모에서 버튼을 추가하여 NSOutlineViewreloadData 메서드의 효과를 보여줍니다. 그리고 이미지에서 볼 수 있듯이 문제가 있습니다 (왼쪽은 reloadData 전화 전, 오른쪽은 reloadData 전화 후). 배지가 사라지고 아이콘이 바뀝니다.Apple SidebarDemo의 이상한 동작

무엇이 문제입니까? NSOutlineViewreloadData을 사용하지 않아야합니까?

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:에 대한 호출 순서는 초기로드와 다시로드 사이에 약간 다릅니다.

솔루션은 고유 한 개체를 사용하여 개요보기에서 각 항목을 나타내는 것입니다. 당신이 있기 때문에이 문제에 물린 될 가능성이있어 실제 코드에서

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

이 달성 SidebarDemo 샘플에 가장 사소한 수정 _childrenDictionary에 저장하기 전에 각는 NSString 값의 변경 가능한 사본을 만드는 것입니다 기본 데이터 객체는 문자열 리터럴로만 구성되는 것이 아니라 모델 클래스의 인스턴스로 구성됩니다.

+0

감사합니다. – Olof