我有一个简单的目录管理器功能,其中的项目类别除了一个项目可以在几个类别中。
项目有“父母”键,即父类别的NSSet
类别有'items'键,是其子项的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
个功能。所以我可以在类别中移动项目。
我的问题: Category1和Category2都包含对相同项目Item1和Item2的引用。我需要Class1中的Item1,Item2顺序和Category2中的Item1顺序。这就是我将category.items属性设为NSOrderedSet
的原因。
但我不能按照category.items
中的索引对项目进行排序我尝试在排序描述符中使用块 - 不起作用,我尝试在排序描述符中使用选择器 - 不起作用,我尝试子类排序描述符 - 以某种方式工作但在更改时不更新项目他们的索引是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;
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设置的索引对项目进行排序。也许有办法通过一些键,运算符,表达式,其他任何东西来做到这一点。感谢。
答案 0 :(得分:2)
我建议你不要使用有序的多对多关系。看起来他们并没有按预期工作,也不符合您的需求。
相反,您需要引入自己的属性来进行排序。您可以拥有与categoryItem
和Category
以及属性Item
具有一对一关系的实体sequence
。
在FRC中,您可以获取categoryItem
实体,在显示时只需使用categoryItem.item
即可访问该项目的属性。当您重新排序时(例如通过拖放),您必须重新编号所有categoryItem
并分配正确的序列号。
- 编辑 -
当项目的某些细节发生变化时,将categoryItem
标记为“脏”:您可以在markDirty
中实现一个方法categoryItem
,如下所示:
// CategoryItem.m
-(void)markDirty {
[self willChangeValueForKey:@"sequence"];
[self didChangeValueForKey:@"sequence"];
}
// EditItemController.m
item.attribute = newAttribute;
for (CategoryItem *i in item.categoryItems) { [i markDirty]; }
答案 1 :(得分:1)
核心数据中的一对多关系是NSSet
s,而不是NSOrderedSet
s。由于这个原因,不保存类别中项目的索引。您可以将另一个实体添加到名为IndexValue
的Core Data模型中。 IndexValue
会有两个属性categoryId
或categoryName
(无论哪个有意义),然后是categoryIndex
。然后Item
将与该实体具有一对多的关系(以及一对一的反向关系,因为不需要重用这些实体,它们应该是唯一的)。对于Category
所在的每个Item
,都会创建IndexValue
。
编辑:似乎添加了有序属性以支持OS X 10.7 and iOS 5中的NSOrderedSet
一对多关系。这必须是您的目标和使用方式。此功能上的文档很少,但在获取关系时不应使用NSSortDescriptor
来保持顺序。至于更改顺序,我不确定这是如何支持的。 Performance on large sets of data is lower使用此方法与我概述的上述方法相比。