繁体   English   中英

具有多个NSFetchedResultsControllers的UITableView导致断言失败

[英]UITableView with multiple NSFetchedResultsControllers causing Assertion failure

我有一个包含3个部分的UITableView,每个部分都通过唯一的NSFetchedResultsController进行馈送。

插入,更新...表时,我从NSFetchedResultsController -controllerDidChangeContent获取断言失败

我的猜测是以下方法中出现indexPaths的问题,因为每个控制器只有一个(0)部分,而对于第0部分中的控制器,不会发生故障。

- (void)controller:(NSFetchedResultsController*)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath*)newIndexPath
{
    switch(type)
    {
        case NSFetchedResultsChangeInsert:
            [[self atableView] insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationLeft];
            break;
        case NSFetchedResultsChangeDelete:
            [[self atableView] deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
            break;
        case NSFetchedResultsChangeUpdate:
            [self configureCell:(DashboardViewCell *) [[self atableView] cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;
        case NSFetchedResultsChangeMove:
            [[self atableView] deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [[self atableView] insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    } 
}

所以我的问题是,如何确定正在处理哪个控制器(从哪个部分开始)并相应地修改indexPath?这是否是正确的方法? 以及在一个uitable视图中使用多个nsfetchedresultsscontrollers的任何示例。

所以我的猜测实际上是正确的:

当每个控制器进入以下功能时

  • (void)控制器:(NSFetchedResultsController *)控制器didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath

除了为第0节设置的控制器以外,每个控制器的indexPath都是错误的。

每个控制器只有一个部分-在我的情况下为0,但更重要的是,这些部分与表部分不对应。

因此,我当前实现的解决方法(不太好,所以可能会重做)是检查控制器的cacheName并基于此修改indexPath / newIndexPath的部分

像这样的东西:

if([[controller cacheName] isEqualToString:@"sectionX"])
{
  indexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:<add correct section>];
  newIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:<add correct section>];
}

我不确定这是FetchedResultController。

插入和删除行调用有时会要求tableView重新加载,然后它将向委托和数据源方法询问numberOfRowsInSection,cellForRowAtIndexPath等。

可能发生的情况是模型和tableView不同步,并导致控制器发出警告。

    [tableView beginUpdates];

     if (editingStyle == UITableViewCellEditingStyleDelete) {

        NSMutableDictionary *item = [self.itemList objectAtIndex:indexPath.row];
    // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [self.itemList removeObjectAtIndex:indexPath.row];      

}   
    [tableView endUpdates];

尝试类似的方法,其中对tableView和基础模型的所有更改都包装在beginUpdates和endUpdates中。 这些将导致tableView等待单元格的绘制,直到您单击“确定”为止。

如果不是上述情况,这就是我通常在tableView中处理多个部分的方式。

在标头中,为各节声明一个typedef枚举;

typedef enum {

    SectionTypeName,
    SectionTypeAge,
    SectionTypeSkills,

} SectionType;

//in the implementation

switch (indexPath.section) {
    case SectionTypeName:
        //do thing in the name section
        break;
    case SectionTypeAge:
        //do thing in the name section
        break;
    case SectionTypeSkills:
        //do thing in the name section
        break;          
    default:
        break;
}

我几乎在每个tableView委托/数据源方法中都有switch()。 这样可以很容易地弄清楚正在处理的部分及其功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM