2014-01-20 44 views
1

當測試我發現outlineView:objectValueForTableColumn:byItem:在最後一個可見行被填充後被調用一個額外的時間導致EXC_BAD_ACCESS錯誤。NSOutlineView ObjectValueForTableColumn額外的調用觸發器不良的訪問

因此,如果我的顯示器顯示10行,在填充第9行之後再次調用objectValueForTableColumn(沒有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。對於最後一個可見行,順序爲:2,3,4,4,4最後一次調用方法#4(outlineView:objectValueForTableColumn:byItem :)導致異常。

我不能告訴你值傳遞給方法,因爲它打破了通話。即使方法中的第一件事是一個日誌語句,它也不會被執行。

所以我很難過。任何想法,爲什麼這是打破?我在執行過程中混淆了嗎?

回答

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

我喜歡那個「順便說一句」,那太棒了。而且你說得對,它還沒有優化,我正在'讓它工作'模式。我可以稍後簡化它。但是在最後一行填滿後,我仍然得到相同的異常。任何想法爲什麼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