使用TableView的核心数据给出断言错误

时间:2015-12-29 03:46:01

标签: ios objective-c uitableview core-data

在删除fetchedresultscontroller委托和tableviewdatasouce的section部分后经过一个小时的代码和编辑后,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编程的初学者,所以我仍然无法得到我错误的错误!上述代码中的任何帮助对我来说都是一次很好的学习经历!

1 个答案:

答案 0 :(得分:0)

简短回答:如果您只希望代码有效,则只需实施controllerDidChangeContent,然后在其中调用[tableView reloadData]

详细地说,对于tableView中的部分更新,它需要更新后的行数等于到它所需的数字。那就是:
原始数字,加上插入单元格和减去删除单元格。

在您的错误中,更新后,您的fetchResultsController有5个对象。 但你只需要调用一次插入。这可能发生在controllerDidChangeContent被调用的fetchResultsController的dataSource再次发生变化之前。

我注意到你的fetchResultController ManagedObjectContext与你创建模型项的那个相同。因此,对于创建的每个项目,fetchResultController响应ManagedObjectContext更改,而不是在保存上下文时批量更改。这应该是你只有一个tableView插入的原因。

如果你真的想要为每一行更改动画,你应该为tableView创建一个copy dataSource,并根据fetch委托通知添加,删除,更新它,而不是直接使用fetchedObjects。通过这种方式,您可以确保表格视图的行数始终等于您的数据源计数,并且不会被其他人更改。