Master Detail Application -
我有UITableViewController
由NSFetchedResultsController
及其委托方法管理。我还在tableview的第一部分中有一个额外的单元格,其中有一个UIWebView
,用于显示嵌入的视频。此单元格不属于NSFetchedResultsController
。我在调用IF
时将其添加到-tableView cellForRowAtIndexPath
语句中,检查它是否是第一部分和第一行。在大多数情况下,一切都很有效。我可以选择一行并在DetailViewController
中显示,我可以删除tableView
中的项目,我可以更改DetailViewController
和tableViewCell
标签更新中的信息出任何问题。
我的问题
我唯一一次设置问题的方法是,当我从tableView
的第一部分删除最后一个对象时。
错误
CoreData:错误:严重的应用程序错误。抓住了一个例外 在调用期间来自NSFetchedResultsController的委托 -controllerDidChangeContent :.无效更新:第0部分中的行数无效。现有部分中包含的行数 更新后(3)必须等于包含的行数 更新前的那一节(2),加上或减去行数 插入或删除该部分(0插入,0删除)和加号 或减去移入或移出该部分的行数(0移动 in,0搬出去了)。 with userInfo(null)
CODE
numberOfRowsInSection
这是我检查视频是否可用以及该部分是否为0返回1个额外行的位置。否则从NSFetchedResultsController
返回对象计数。我假设这是我的问题所在。但是,我不知道如何解决它。因为我有NSFetchedResultsController
委托方法管理的,所以我可以在switch语句中的“type”中做任何事情吗?
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0 && self.videoInfoReceived == YES) {
id <NSFetchedResultsSectionInfo> secInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [secInfo numberOfObjects] + 1;
} else {
id <NSFetchedResultsSectionInfo> secInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [secInfo numberOfObjects];
}
}
NSFetchedResultsController委托
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
NSLog(@"didChangeSection - ChangeInsert");
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
NSLog(@"didChangeSection - ChangeDelete");
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
NSLog(@"didChangeObject - ChangeInsert");
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
NSLog(@"didChangeObject - ChangeDelete");
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
NSLog(@"didChangeObject - ChangeUpdate");
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
NSLog(@"didChangeObject - ChangeMove");
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
}
答案 0 :(得分:1)
您需要更多条件代码来检查您发送的任何索引路径是否属于第一个(零)部分。如果是,则FRC被赋予“错误的”行号,因为您已经告诉表视图一行计数而FRC理解另一行。
基本上,无论您从表格视图收到索引路径,请查看该部分== 0
,创建具有相同部分的新索引路径row - 1
并使用它来访问FRC中的对象。
相反,当您从FRC 收到索引路径时,您需要row + 1
才能使用它来请求表格视图插入/删除/移动。
答案 1 :(得分:0)
在你的问题中,你说:
当我从tableView
的第一部分删除最后一个对象时
这会让我期望异常声明以下内容(强调添加):
CoreData:错误:严重的应用程序错误。在调用-controllerDidChangeContent:期间,从NSFetchedResultsController的委托中捕获到异常。更新无效:第0部分中的行数无效。更新后的现有部分中包含的行数(0)必须等于该部分中包含的行数更新(1),加上或减去从该部分插入或删除的行数(0插入,1删除)以及加或减移入或移出的行数部分(0移入,0移出)。 with userInfo(null)
因为异常表明行计数从<2>增加而没有添加任何行,所以我认为您的错误在模型层中而不在表视图代码中。您的表格视图代码对我来说很棒。