NSFetchedResultsController 期望返回准确的行数

NSFetchedResultsController expects exact number of rows to be returned

我有一个 NSFetchedResultsController 配置为在 UITableView 中加载某种类型的对象。下面是执行此操作的代码示例:

    __weak __typeof(self)weakSelf = self;
[[FSRDataManager sharedManager] loadViolationsForSection:FSRViolationEntityUnitIdAttribute
                                                 success:^(BOOL successful, NSFetchedResultsController *results) {
                                                     weakSelf.violations = results;
                                                     weakSelf.violations.delegate = weakSelf;
                                                     [weakSelf.tableView reloadData];

                                                     [weakSelf fetchViolations];
                                                 }
                                                 failure:^(NSError *error) {
                                                     [weakSelf displayAlertForError:error];

                                                     [weakSelf fetchViolations];
                                                 }];

FRC 有一个 sectionNameKeyPath,因为我想以分段格式显示数据。

fetchViolations 从服务器获取数据并将其存储在 Persistent Storage 中并更新 Managed Object Context。在此更新中,我收到了对 -controllerWillChange:-controllerDidChange: 的委托调用,这是正常的。然而,当这些变化发生时,tableview 的 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 被调用。

在那里我 returning 行数并不总是 NSFetchedResultsSectionInfo 对象中的对象数,如下所示:

        rows = 1;
        for (NSIndexPath *i in self.expandedIndexPaths) {
            if (i.section == section) {
                id<NSFetchedResultsSectionInfo> s = self.violations.sections[section];
                rows += s.numberOfObjects;
            }
        }

如您所见,我正在检查 indexPath 是否在数组中,然后我才将该部分信息对象中的 numberOfObjects 添加到固定数字,(1) 在这种情况下。

但是,这样做会引发 CoreData 错误,而我的 UITableView 全部 "wonky"。

这是抛出的错误:

*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318.93/UITableView.m:1314
CoreData: error: Serious application error.  An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:.  attempt to delete row 6 from section 71 which only contains 1 rows before the update with userInfo (null)

如果我只是 return 部分信息对象中的对象数量,它就可以正常工作。有什么办法可以绕过这个吗?让我return我要多少行?

你不能 'bypass' 这个,如果不以类似的方式修改 FRC 委托方法,你就无法使用该方法。该错误表明您正在尝试将所有 FRC 委托回调更改应用到 table 视图,即使您的行计数方法进行了非常具体的过滤也是如此。这会导致发送到 table 视图的更改请求与为每个部分提供的行数不匹配。

最简单的选择是不使用来自 FRC 的增量更改回调,而是在 FRC 报告每次更改后在 table 视图上简单地调用 reloadData

如果您想为个别更改启用动画,则需要过滤这些更改,并仅将对行计数有相应更改的更改应用。