CoreData:按类别集中的索引sorting项目

我有一个简单的目录pipe理器function与类别中的项目除了一个项目可以在几个类别。

项目具有父母类别的NSSet的“父母”键

类别具有其子项NSOrderedSet的“项目”键

我正在使用NSFetchedResultController和它的委托来填充我的表与项目

 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(ANY parents == %@)", self.category]; [fetchRequest setFetchBatchSize:30]; [fetchRequest setSortDescriptors:@[????????]; NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil]; aFetchedResultsController.delegate = self; self.fetchedResultsController = aFetchedResultsController; NSError *error = nil; if (![self.fetchedResultsController performFetch:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } 

所以使用这个代码我可以得到self.category中的项目列表

在我的用户界面,我有Drag and Dropfunction。 所以我可以移动项目内的类别。

我的问题: Category1和Category2都包含相同的项目Item1和Item2的引用。 我需要在Category1和Item2中的Item1,Item2顺序,在Category2中的Item1顺序。 这就是为什么我把category.items属性作为NSOrderedSet

但是我不能按照category.items中的索引来sorting项目

我试图使用sorting描述符块 – 没有工作,我试图在sorting描述符中使用select器 – 没有工作,我试图子类sorting描述符 – 以某种方式工作,但不更新项目时,我改变他们的索引category.items。
就像我在NSSortDescriptorSubclass中一样:

- (NSComparisonResult)compareObject:(Item*)object1 toObject:(Item*)object2 {

 int index1 = [self.category.items indexOfObject:object1]; int index2 = [self.category.items indexOfObject:object2]; if (index1 > index2) { return NSOrderedDescending; } else if (index1 < index2) { return NSOrderedAscending; } return NSOrderedSame; 

}但是,如果我在Category.items中更改顺序,项目顺序将不会在我的用户界面中更新

所以,请帮助我按category.items中的索引对项目进行sorting。 也许有一种方法可以通过一些键,运算符,expression式来实现。 谢谢。

我build议你不要使用有序的多对多关系。 看起来他们并不像预期的那样工作,也不符合你的需求。

相反,您需要引入您自己的属性来进行sorting。 你可以有一个实体categoryItem ,它与CategoryItem以及属性sequence都有一对一的关系。

在FRC中,您可以获取categoryItem实体,并在显示时使用categoryItem.item访问该项目的属性。 当您重新sorting(例如通过拖放)时,您必须对所有categoryItem进行重新编号并分配正确的序号。

– 编辑 –

要在项目的某些细节发生变化时将categoryItem标记为“脏”:您可以在categoryItem中实现一个方法markDirty ,如下所示:

 // CategoryItem.m -(void)markDirty { [self willChangeValueForKey:@"sequence"]; [self didChangeValueForKey:@"sequence"]; } // EditItemController.m item.attribute = newAttribute; for (CategoryItem *i in item.categoryItems) { [i markDirty]; } 

核心数据中的一对多关系是NSSet ,而不是NSOrderedSet 。 由于这个原因,一个类别中的一个项目的索引不被保存。 你可以添加另一个实体到你的核心数据模型中,比如IndexValueIndexValue将有两个属性, categoryIdcategoryName (无论哪个有意义),然后是categoryIndex 。 然后Item与这个实体有一对多的关系(和一对一的反向关系,因为不需要重用这些实体,它们应该是唯一的)。 对于Item所在的每个Category ,都会创build一个IndexValue

编辑:似乎有序的属性被添加到支持OS X 10.7和iOS 5的 NSOrderedSet一对多的关系。 这一定是你的目标和使用。 文档在这个特性上是稀疏的,但是在获取关系时不需要使用NSSortDescriptor可以保持顺序。 至于改变顺序,我不知道如何支持。 与上述方法相比,使用此方法的大型数据集的性能更低 。