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
。
如果您想为个别更改启用动画,则需要过滤这些更改,并仅将对行计数有相应更改的更改应用。
我有一个 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
。
如果您想为个别更改启用动画,则需要过滤这些更改,并仅将对行计数有相应更改的更改应用。