CoreData:按类别集中的索引对项目进行排序 [英] CoreData: Sort items by index in category's set

查看:471
本文介绍了CoreData:按类别集中的索引对项目进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



商品的父级键是NSSet的父类别



strong> Category 有'items'键,它的子项的NSOrderedSet



我使用 NSFetchedResultController 和它的委托给我的表填充项

  NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription * entity = [NSEntityDescription entityForName:@IteminManagedObjectContext: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中的项目列表



在我的用户界面中,我有拖放功能。



我的问题:类别1和类别2都包含对相同项目Item1和Item2的引用。我需要有Item1,Item2订单在Category1和Item2,Item1订单在Category2。这就是为什么我做category.items属性为 NSOrderedSet



但我只是不能通过他们的索引类别.items



我试图在排序描述符中使用块 - 没有工作,我试图在排序描述符中使用选择器 - 没有工作,我试图子类化排序描述符 - 以某种方式工作,但是当我更改其索引时,它不会更新类category.items。

像这样在我的NSSortDescriptorSubclass:




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

 code> 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中的索引对项目进行排序。也许有一种方法通过一些键,运算符,表达式,其他任何东西。感谢。

解决方案

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



相反,你需要引入自己的属性来做排序。您可以有一个实体 categoryItem 类别项目以及属性序列



在您的FRC中,您将获取 categoryItem 实体,并且在显示时只需使用 categoryItem。 item 以访问项目的属性。当你重新排序(例如通过拖放)你必须重新编号所有 categoryItem ,并分配正确的序列号。



- EDIT -



当项目的某些细节更改时,将 categoryItem 标记为dirty :您可以在 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]; }


I have a simple catalog manager functionality with items in categories EXCEPT one Item can be in several Categories.

Item has 'parents' key which is NSSet of parent categories

Category has 'items' key which is NSOrderedSet of its subitems

I am using NSFetchedResultController and its delegate to fill my table with items

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();
}

So using this code I can get the list of items in self.category

In my UI I have Drag and Drop functionality. So I can move Items inside categories.

My question: Category1 and Category2 both contain references to the same items Item1 and Item2. I need to have Item1, Item2 order in Category1 and Item2, Item1 order in Category2. That's why I made category.items property as NSOrderedSet.

But I just cannot sort Items by their index in category.items

I tried to use blocks in sort descriptors - didn't work, I tried to use selectors in sort descriptors - didn't work, I tried to subclass sort descriptors - works somehow but doesn't update Items when I am changing their index it category.items.
Like this in my 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;

} But items order won't be updated in my UI if I change order in Category.items

So please, help me to sort items by their index in category.items set. Maybe there is a way to do that through some keys, operators, expressions, anything else. Thanks.

解决方案

I recommend you do not use ordered to-many relationships. It seems that they are not really working as expected and do not fit your needs.

Instead, you need to introduce your own attribute to do the sorting. You could have an entity categoryItem that has to-one relationships to both Category and Item as well as an attribute sequence.

In your FRC you fetch the categoryItem entity and when displaying you just use categoryItem.item to access the properties of the item. When you reorder (e.g. via drag and drop) you have to renumber all categoryItems and assign the correct sequence number.

-- EDIT --

To mark the categoryItem as "dirty" when some detail of an item changes: you can implement a method markDirty in categoryItem that looks like this:

// CategoryItem.m
-(void)markDirty {
    [self willChangeValueForKey:@"sequence"];
    [self didChangeValueForKey:@"sequence"];
}

// EditItemController.m
item.attribute = newAttribute; 
for (CategoryItem *i in item.categoryItems) { [i markDirty]; }

这篇关于CoreData:按类别集中的索引对项目进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆