CoreData:按类别集中的索引对项目进行排序

时间:2013-04-02 15:47:51

标签: ios sorting core-data

我有一个简单的目录管理器功能,其中的项目类别除了一个项目可以在几个类别中。

项目有“父母”键,即父类别的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

中更改订单,则不会在我的UI中更新商品订单

所以请帮助我按照category.items设置的索引对项目进行排序。也许有办法通过一些键,运算符,表达式,其他任何东西来做到这一点。感谢。

2 个答案:

答案 0 :(得分:2)

我建议你不要使用有序的多对多关系。看起来他们并没有按预期工作,也不符合您的需求。

相反,您需要引入自己的属性来进行排序。您可以拥有与categoryItemCategory以及属性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会有两个属性categoryIdcategoryName(无论哪个有意义),然后是categoryIndex。然后Item将与该实体具有一对多的关系(以及一对一的反向关系,因为不需要重用这些实体,它们应该是唯一的)。对于Category所在的每个Item,都会创建IndexValue

编辑:似乎添加了有序属性以支持OS X 10.7 and iOS 5中的NSOrderedSet一对多关系。这必须是您的目标和使用方式。此功能上的文档很少,但在获取关系时不应使用NSSortDescriptor来保持顺序。至于更改顺序,我不确定这是如何支持的。 Performance on large sets of data is lower使用此方法与我概述的上述方法相比。