2014-01-20 3 views
1

테스트 할 때 마지막으로 표시된 행이 채워진 후 EXC_BAD_ACCESS 오류가 발생하여 outlineView : objectValueForTableColumn : byItem :이 추가 시간 동안 호출되고 있음을 발견했습니다.NSOutlineView ObjectValueForTableColumn 추가 호출 트리거 잘못된 액세스

내 디스플레이가 10 행을 표시하는 경우 행 9가 채워진 후 outlineValueForTableColumn이 다시 호출됩니다 (outlineView : child : ofItem : 및 outlineView : isItemExpandable : 호출되지 않음). 추가 호출은 마지막으로 표시된 행이 채워진 후에 항상 발생합니다.

다음은 outlineView의 코드입니다. 테스트 데이터 세트에는 2 개의 열과 114 개의 레코드가 있습니다.

// (1) 
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item { 
    if (!item) { 
     NSInteger parentCount = [[Parent countParents:self.dataSetID usingManagedObjectContext:self.context] integerValue]; 
     return parentCount; 
    } 
    Parent *thisParent = item; 
    NSInteger childCount = [[thisParent.child allObjects] count]; 
    return childCount; 
} 

// (2) 
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item { 
    NSArray *parentArray = [Parent parentData:self.dataSetID usingManagedObjectContext:self.context]; 
    Parent *thisParent = [parentArray objectAtIndex:index]; 
    if (!item) { 
     return thisParent; 
    } 
    NSArray *children = [NSArray arrayWithObject:[thisParent.child allObjects]]; 
    Child *thisChild = [children objectAtIndex:index]; 
    return thisChild; 
} 

// (3) 
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item { 
    if ([item isKindOfClass:[Parent class]]) { 
     Parent *thisParent = item; 
     if ([[thisParent.child allObjects] count] > 0) { 
      return YES; 
     } 
    } 
    return NO; 
} 

// (4) 
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { 
    if (!item) { 
     return nil; 
    } 
    if ([tableColumn.identifier isEqualToString:@"column1"]) { 
     if ([item isKindOfClass:[Parent class]]) { 
      Parent *thisParent = item; 
      return thisParent.name; 
     } 
     Child *thisChild = item; 
     return thisChild.name; 
    } 
    // This is column2 
    if ([item isKindOfClass:[Parent class]]) { 
     Parent *thisParent = item; 
     return thisParent.age; 
    } 
    Child *thisChild = item; 
    return thisChild.age; 
} 

나는 방법을 순서대로 호출되는 것으로 나타났습니다 : 1,2,3,4,4,2,3,4,4 ... 두 열 NSOutlineView을 채우는. 마지막으로 보이는 행의 경우 순서는 다음과 같습니다. 예외를 유발하는 메소드 # 4 (outlineView : objectValueForTableColumn : byItem :)에 대한 마지막 호출이있는 2,3,4,4,4.

통화가 끊어지기 때문에 메서드에 전달되는 값을 말할 수 없습니다. 메서드의 첫 번째 것이 로그 문이라도 실행되지는 않습니다.

그래서 나는 혼란 스럽습니다. 이게 왜 깨지는 지 아십니까? 구현에 관해서 나왔나?

답변

0

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item에서는 item를 사용하는 표시되지 않습니다 - 당신은 child item at the specified index of a given item를 반환해야합니다.

덧붙여 말하자면 코드가 비효율적이므로 가능한 한 빨리 실행해야합니다. 당신은 아마 원할 것입니다 : -

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item { 
    if (item == nil) 
     return [[Parent parentData:self.dataSetID usingManagedObjectContext:self.context] objectAtIndex:index]; 
    return [[NSArray arrayWithObject:[item.child allObjects]] objectAtIndex:index]; 
} 
+0

나는 "우연히"그게 굉장합니다. 그리고 당신은 맞습니다. 아직 최적화되지 않았습니다. 저는 'make it work'모드에 있습니다. 나는 나중에 그것을 합리화 할 수있다. 하지만 마지막 행이 채워진 후에도 여전히 동일한 예외가 발생합니다. objectValueForTableColumn이 여분의 호출을 얻는 이유는 무엇입니까? 나는 가능한 한 그것을 피하려고 노력하고 있지만 솔루션으로 바인딩을 조사해야 할 수도 있습니다. – Chris

+1

NSOutlineViewDataSource의 세부 사항을 알지 못하면 문제의 원인을 찾아 내기가 어렵습니다. '[NSArray arrayWithObject : [item.child allObjects]]'가 최적화되지 않은 코드 인 경우에도 불필요한 것처럼 보이지만 오류를 수정했다면 문제가 없다고 지적했습니다. 처음 사용했을 때 각 메소드에서'item'과'index'를 출력했습니다. – Milliways

+0

좋아,이 시간을 찾기 위해 며칠이 걸렸지 만 데이터 소스로 그걸 가져갔습니다. 내 데이터 소스를이 답변의 형식으로 수정했습니다. http://stackoverflow.com/questions/6664898/nsoutlineview-example/9387255#9387255 그 트릭을했습니다. 또한 데이터 소스가 준비되기 전에 OutlineView를 숨기면 준비가 완료되기 전에로드되지 않으며 [outlineView reloadData]를 사용하여 아웃 라인보기의 채우기를 트리거한다는 것을 알게되었습니다. 도와 주셔서 대단히 감사합니다! – Chris