使用 NSFetchedResultsController 在 tableView 中没有数据视图

Posted

技术标签:

【中文标题】使用 NSFetchedResultsController 在 tableView 中没有数据视图【英文标题】:No data view in tableView using NSFetchedResultsController 【发布时间】:2017-02-19 19:16:24 【问题描述】:

我在我的表格视图中使用NSFetchedResultsController,它工作正常。我的问题是,当我的_fetchedResultsController 有 0 行时,我想创建“无数据视图”。

我尝试像这样在我的numberOfSectionsInTableView: 中创建它

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    if ([[_fetchedResultController.sections firstObject] numberOfObjects] == 0) 
        MyNoDataView *view = [[MyNoDataView alloc] initWithFrame:tableView.frame];
        tableView.backgroundView = view;
        tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        return 0;
    
    else 
        tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
        tableView.backgroundView = nil;
        return  1;  
    

效果很好。如果还没有插入数据,则显示没有数据视图,如果有数据,它将显示我的表格视图。

当我对其行执行删除操作时,我的问题就开始了。从技术上讲,我只是将它的对象属性(isActive)更新为我在fetchedResultController 中的fetchRequest,使用这个NSPredicate

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"isActive == %@ ", @YES];
[fetchRequest setPredicate:predicate];

然后,如果只有 1 行,我删除它,我得到这个错误

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView internal bug: unable to generate a new section map with old section count: 1 and new section count: 0'

所以我试图删除我的numberOfSectionsInTableView:,突然这些错误就消失了。我不知道这里发生了什么,但我认为numberOfSectionsInTableView: 的条件有一个错误。

任何帮助将不胜感激。非常感谢!

【问题讨论】:

检查副本。您需要在 NSFetchedResultsController 委托方法中处理此问题。如果您要添加自定义单元格和部分,NSFetchedResultsController“不知道”。它只是提供它自己的数据,并从它自己的帐户中插入单元格和部分,如果你已经有单元格和部分,那么数字不会正确添加 upp,你会崩溃。另外,sidenote 为什么还要分配“MyNoDataView”并在 numberOfSectionsInTableView 中设置分隔符样式?这真的是非常糟糕的做法。 EDIT 我删除了重复的标志。提供更多关于如何处理插入和删除等的代码。这样我们就可以更容易地找到错误。也许这可以帮助您搜索错误代码:***.com/questions/33951169/… 和 forums.developer.apple.com/thread/9964 我只想创建无数据视图。那么你认为我应该如何分配我的 MyNoDataView 并将其作为 tableview 背景?提前谢谢你。 没错。您甚至可以提供 EmptyDataCell ,并在获取的内容为空时返回 cellForRowAtIndexPath 中的空单元格。在您的 controller.delegate 方法中,您只需要在空到内容或内容到空之间切换时重新加载数据。否则你让委托方法正常运行:) 谢谢,非常感谢!现在我将尝试修改它的委托。再次感谢您! 【参考方案1】:

已解决

基于Sneak 的回答,分配“MyNoDataView”并在 numberOfSectionsInTableView 中设置分隔符样式确实是非常糟糕的做法。所以我最终在获取的结果控制器委托上修改了我的controllerDidChangeContent:

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    if ([controller.fetchedObjects count]) 
        self.tableView.backgroundView = nil;
    
    else 
        MyDataView *view = [[MyDataView alloc] initWithFrame:self.tableView.frame];
        self.tableView.backgroundView = view;
    

    [self.tableView endUpdates];

【讨论】:

感谢您发布解决方案。我也有类似性质的问题。现在修好了。 @sweta.me 很高兴听到这个消息!

以上是关于使用 NSFetchedResultsController 在 tableView 中没有数据视图的主要内容,如果未能解决你的问题,请参考以下文章

核心数据保存竞争条件错误

在 Swift 3 中难以配置 NSFetchedResultsController

为啥 beginUpdates/endUpdates 会重置表视图位置以及如何阻止它这样做?

测试使用

第一篇 用于测试使用

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?