Cocoa 不能同时添加子对象和父对象
我有一个CoreData支持的应用程序,它代表某种文件夹层次结构 因此文件夹可以有一个子文件夹 因此,Cocoa 不能同时添加子对象和父对象,cocoa,core-data,nsfetchedresultscontroller,nsfetchrequest,Cocoa,Core Data,Nsfetchedresultscontroller,Nsfetchrequest,我有一个CoreData支持的应用程序,它代表某种文件夹层次结构 因此文件夹可以有一个子文件夹 因此,NSManagedObject父对象和子对象之间的关系 服务器端目前只支持两级层次结构。 主文件夹->子文件夹 但为了为未来做好准备,CoreData模型旨在支持无限量的级别 所以这种关系是 parent <------>> children 这很好,但当FRC的委托方法启动时,我将得到以下错误: CoreData: error: Serious application er
NSManagedObject
父对象和子对象之间的关系
服务器端目前只支持两级层次结构。
主文件夹->子文件夹
但为了为未来做好准备,CoreData模型旨在支持无限量的级别
所以这种关系是
parent <------>> children
这很好,但当FRC的委托方法启动时,我将得到以下错误:
CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. attempt to insert row 0 into section 3, but there are only 0 rows in section 3 after the update with userInfo (null)
看来,FRC在新的部分和插入的行上绊倒了。
但我还没有找到解决这个问题的办法。即使我在创建并保存主文件夹后创建并添加了systemChildSubfolder
,我仍然会遇到这个错误。
似乎FRC仍然返回旧的节数,并试图在错误的节中添加新行
因此,任何人都可以向我解释如何让FRC像我期望的那样工作:
首先添加节,然后添加行
财务汇报局代表:
#pragma mark - NSFetchedResultsControllerDelegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[[self folderTableView] beginUpdates];
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch (type) {
case NSFetchedResultsChangeInsert:
[[self folderTableView] insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
return;
case NSFetchedResultsChangeDelete:
[[self folderTableView] deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
return;
default:
return;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
switch(type) {
case NSFetchedResultsChangeInsert:
[[self folderTableView] insertRowsAtIndexPaths:@[newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[[self folderTableView] deleteRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
{
UITableViewCell * tableViewCell = [[self tableView] dequeueReusableCellWithIdentifier:TableViewCellIdentifier forIndexPath:indexPath];
Folder * folder = [[self fetchedResultsController] objectAtIndexPath:indexPath];
[self configureTableViewCell:tableViewCell withFolder:folder];
}
break;
case NSFetchedResultsChangeMove:
[[self folderTableView] insertRowsAtIndexPaths:@[newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
[[self folderTableView] deleteRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[[self folderTableView] endUpdates];
}
#pragma标记-NSFetchedResultsControllerDelegate
-(void)controllerWillChangeContent:(NSFetchedResultsController*)控制器{
[[self folderTableView]开始更新];
}
}
-(void)控制器:(NSFetchedResultsController*)控制器didChangeSection:(id)sectionInfo atIndex:(nsInteger)ChangeType的sectionIndex:(NSFetchedResultsChangeType)类型
{
开关(类型){
案例NSFetchedResultsChangesInsert:
[[self-folderTableView]insertSections:[NSIndexSet IndexSetWithiIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
返回;
案例NSFetchedResultsChangeDelete:
[[self-folderTableView]deleteSections:[NSIndexSet IndexSetWithiIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
返回;
违约:
返回;
}
}
-(void)控制器:(NSFetchedResultsController*)控制器didChangeObject:(id)一个对象
atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)类型
newindepath:(nsindepath*)newindepath
{
开关(类型){
案例NSFetchedResultsChangesInsert:
[[self-folderTableView]InsertRowsatindExpath:@[newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeDelete:
[[self-folderTableView]DeleteRowsatindExpath:@[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeUpdate:
{
UITableViewCell*tableViewCell=[[self tableView]dequeueReusableCellWithIdentifier:TableViewCellIdentifier for indexPath:indexPath];
Folder*Folder=[[self-fetchedResultsController]objectAtIndexPath:indexPath];
[自配置tableViewCell:tableViewCell with folder:folder];
}
打破
案例NSFetchedResultsChangeMove:
[[self-folderTableView]InsertRowsatindExpath:@[newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
[[self-folderTableView]DeleteRowsatindExpath:@[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
打破
}
}
-(void)controllerDidChangeContent:(NSFetchedResultsController*)控制器
{
[[self-folderTableView]EndUpdate];
}
简短更新:
我的怀疑是,尽管FRC有一个childfolder,但它并没有为新的家长更新
但新子级的更新具有正确的IndexPath(如果其父级在FRC中),但与FRC中存储的内容不匹配。2级
正如评论中所指出的,您的设置在两个以上的级别是不可行的。因为您只想处理父项和子项,所以我推荐以下简单的解决方案:
创建两个实体,main文件夹
和子文件夹
。如果愿意,您可以有一个文件夹
类型的抽象父实体,但这并不是绝对必要的
MainFolder (subFolders) <------>> (mainFolder) SubFolder
MainFolder(子文件夹)>(MainFolder)子文件夹
获取子文件夹
并使用main文件夹
作为` sectionNameKeyPath'
就这样,再简单不过了
无限级 如果您想要实现一个潜在的无限层次结构,那么您可能应该在这个设置开始工作后问一个新问题 提示:您只有一种实体,
文件夹
,它也有一个属性级别
。创建文件夹并设置父级时,您需要检查级别,并将自己的级别设置为父级的级别加一。层次结构上下的关系是自反的,即引用相同的文件夹
实体
在FRC中,您将获取不带sectionNameKeyPath
的父项(通过基于级别的谓词),对节使用objectAtIndexPath
,并根据文件夹填充节下面的行。子项
位于相应的表视图数据源
方法中(numberOfRowsInSection
和cellforrowatinexpath
)。为什么它不是“parent==nil”
如果您希望支持任意深度,并允许用户向下搜索。您当前的界面不会显示层次结构,它将是一个非常大的分区列表……它还可以避免您为管理创建的文件夹。行是子文件夹,它们确实有父文件夹。父文件夹将在分区中表示。这就是l工作正常,正确,问题出在FRC的某个地方,它被授权了,但是当你添加第三个深度的文件夹时
MainFolder (subFolders) <------>> (mainFolder) SubFolder