【问题标题】:UITableView with multiple NSFetchedResultsControllers causing Assertion failure具有多个 NSFetchedResultsControllers 的 UITableView 导致断言失败
【发布时间】:2011-01-12 12:16:02
【问题描述】:

我有一个包含 3 个部分的 UITableView,每个部分都通过唯一的 NSFetchedResultsController 提供。

在插入、更新...表时,我从 NSFetchedResultsController -controllerDidChangeContent 收到 Assertion failure

我的猜测是 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 以及这样做是否正确?可能还有使用多个 nsfetchedresultscontroller 和一个 uitableview 的任何示例。

【问题讨论】:

    标签: xcode uitableview ios nsfetchedresultscontroller


    【解决方案1】:

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

    随着每个控制器进入以下功能

    • (void)controller:(NSFetchedResultsController*)controller 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>];
    }
    

    【讨论】:

    • 感谢您节省时间 ;) newIndexPath 的一个小错误。应该是[NSIndexPath indexPathForRow:newIndexPath.row inSection:&lt;add correct section&gt;]
    【解决方案2】:

    我不确定它是 FetchedResultController。

    insert 和 delete 行调用会在某些时候要求 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()。 这样可以很容易地确定正在处理的部分以及它的作用。

    【讨论】:

      猜你喜欢
      • 2018-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-17
      • 2020-10-19
      • 2015-02-13
      • 2014-05-26
      • 2013-02-25
      相关资源
      最近更新 更多