2015-12-29 43 views
0

去除fetchedresultscontroller代表和tableviewdatasouce第一部分之後經歷代碼和編輯一個小時後,的tableView正確顯示的項目:核心數據與TableView中得到斷言錯誤

CoreDataTVC:

-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSections:(NSInteger)section 
    { 
     if(debug==1) NSLog(@"Running %@ '%@'",self.class,NSStringFromSelector(_cmd)); 
     return [[self.frc.sections objectAtIndex:section] numberOfObjects]; 
    } 

    -(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView 
    { 
     if(debug==1) NSLog(@"Running %@ '%@'",self.class,NSStringFromSelector(_cmd)); 
     return [[self.frc sections] count]; 
    } 

    -(NSInteger)tableView:(UITableView*)tableView sectionForSectionIndexTitle:(NSString*)title atIndex:(NSInteger)index 
    { 
     if(debug==1) NSLog(@"Running %@ '%@'",self.class,NSStringFromSelector(_cmd)); 
     return [self.frc sectionForSectionIndexTitle:title atIndex:index]; 
    } 

    -(NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section 
    { 
     if(debug==1) NSLog(@"Running %@ '%@'",self.class,NSStringFromSelector(_cmd)); 
     return [[[self.frc sections] objectAtIndex:section] name]; 
    } 

    -(NSArray*)sectionIndexTitlesForTableView:(UITableView*)tableView 
    { 
     if(debug==1) NSLog(@"Running %@ '%@'",self.class,NSStringFromSelector(_cmd)); 
     return [self.frc sectionIndexTitles]; 
    } 

-(void)controller:(NSFetchedResultsController*)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type 
{ 
    if(debug==1) NSLog(@"Running %@ '%@'",self.class,NSStringFromSelector(_cmd)); 

    switch(type) 
    { 
     case NSFetchedResultsChangeInsert: 
      [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic]; 
      break; 
     case NSFetchedResultsChangeDelete: 
      [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
     case NSFetchedResultsChangeMove: 
      break; 
     case NSFetchedResultsChangeUpdate: 
      break; 
    } 
} 

-(void)controller:(NSFetchedResultsController*)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath*)newIndexPath 
{ 
    if(debug==1) NSLog(@"Running %@ '%@'",self.class,NSStringFromSelector(_cmd)); 
    switch(type) 
    { 
     case NSFetchedResultsChangeInsert: 
      [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 
      break; 
     case NSFetchedResultsChangeDelete: 
      [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
     case NSFetchedResultsChangeMove: 
      [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 
      break; 
     case NSFetchedResultsChangeUpdate: 
      if(!newIndexPath) 
      { 
       [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; 
      }else 
      { 
       [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
       [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 
      } 
      break; 
    } 
} 

我我真的是ios編程的初學者,所以我仍然不明白我做錯了錯誤!上述代碼中的任何幫助對我來說都是一次很好的學習體驗!

回答

0

簡短的回答:如果你只想要你的代碼工作,你只需要實現controllerDidChangeContent,並在那裏,請撥打[tableView reloadData]

詳細地說,對於tableView中的部分更新,它需要更新後的行數爲等於到它所需的數目。即:
原始數字,加上插入單元格和減去刪除單元格。

在你的錯誤,更新後,你的fetchResultsController有5個對象。 但你只能調用插入一次。這可能發生在您調用controllerDidChangeContent之前,fetchResultsController的dataSource再次發生更改。

我注意到你的fetchResultController的ManagedObjectContext和你創建模型項目的一樣。因此對於創建的每個項目,fetchResultController都會響應ManagedObjectContext更改,而不是在保存上下文時進行批量更改。這應該是爲什麼你只有一個tableView插入的原因。

如果你真的想動畫改變每一行,你應該爲tableView創建一個副本dataSource,並根據fetch delegate notify來添加,刪除,更新它,而不是直接使用fetchedObjects。這樣,您可以確保表視圖的行數始終等於您的dataSource計數,並且不會被其他人更改。

+0

如果我想使用委託方法,我應該改變什麼? – hengecyche

+0

@hengecyche只實現'controllerDidChangeContent',並在那裏調用'[tableView reloadData]'。不要暗示其他委託方法。 – SolaWing

+0

@hengecyche如果您的應用程序是單線程應用程序,您可以看到啓用CoreData的Xcode新項目模板。 – SolaWing