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 Drop
function。 所以我可以移动项目内的类别。
我的问题: 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
,它与Category
和Item
以及属性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
。 由于这个原因,一个类别中的一个项目的索引不被保存。 你可以添加另一个实体到你的核心数据模型中,比如IndexValue
。 IndexValue
将有两个属性, categoryId
或categoryName
(无论哪个有意义),然后是categoryIndex
。 然后Item
与这个实体有一对多的关系(和一对一的反向关系,因为不需要重用这些实体,它们应该是唯一的)。 对于Item
所在的每个Category
,都会创build一个IndexValue
。
编辑:似乎有序的属性被添加到支持OS X 10.7和iOS 5的 NSOrderedSet
一对多的关系。 这一定是你的目标和使用。 文档在这个特性上是稀疏的,但是在获取关系时不需要使用NSSortDescriptor
可以保持顺序。 至于改变顺序,我不知道如何支持。 与上述方法相比,使用此方法的大型数据集的性能更低 。