复杂对象上的自定义NSSortDescriptor [英] Custom NSSortDescriptor on complex object
问题描述
这是我的第一篇文章这么抱歉,如果我不尊重所有的约定,尽管我会尽我所能。我总是找到解决我的问题在SO之前,但我完全停留在一个相当复杂的Cocoa问题。
It's my first post so sorry if I may not respect all the conventions even though I'll try my best. I have always found solutions to my problems on SO before but I'm completely stuck on a rather complex Cocoa problem.
我试图实现一个复杂的排序列表的CoreData对象。我有一个目录组成的书对象,它可以是佐贺的一部分(第一本书及其续集)。简单的结构看起来像这样:
I am trying to achieve a complex sort on a list of CoreData objects. I have a catalog composed of Book objects, which can be part of Saga (first book and its sequels). The simplified structures look like this:
@interface Book : NSManagedObject
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSNumber * tomaison; //volume numbering
@property (nonatomic, retain) Saga *fromSaga;
@interface Saga : NSManagedObject
@property (nonatomic, retain) NSString * title;
我试图对我的CoreData数据库执行查询:
I'm trying to perform a query on my CoreData db, on Book:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:context];
我需要三个步骤:
1)按照书籍的类型排序(不包括在上面的代码中,因为不需要它):
1) Sort by book's Genre (not included in the code above because it's not needed), which is performed with:
NSSortDescriptor* mainSort = [[NSSortDescriptor alloc] initWithKey:@"ofGenre.title" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
2)按Saga标题排序,如果这本书是佐贺的一部分
2) Sort by Saga title if the book is part of a Saga
NSSortDescriptor* secondarySort = [[SagaTitleSortDescriptor alloc] initWithKey:@"fromSaga" ascending:YES];
自定义排序描述符由以下内容定义:
Where the custom sort descriptor is defined by:
#define NULL_OBJECT(a) ((a) == nil || [(a) isEqual:[NSNull null]])
@interface SagaTitleSortDescriptor : NSSortDescriptor {}
@end
@implementation SagaTitleSortDescriptor
- (id)copyWithZone:(NSZone*)zone
{
return [[[self class] alloc] initWithKey:[self key] ascending:[self ascending] selector:[self selector]];
}
- (NSComparisonResult)compareObject:(id)object1 toObject:(id)object2
{
if (NULL_OBJECT([object1 valueForKeyPath:[self key]])) {
if (NULL_OBJECT([object2 valueForKeyPath:[self key]]))
return NSOrderedSame;
return NSOrderedDescending;
}
if (NULL_OBJECT([object2 valueForKeyPath:[self key]])) {
return NSOrderedAscending;
}
return [super compareObject:[(Saga*)object1 title] toObject:[(Saga*)object2 title]];
}
@end
3)按卷编号排序的佐贺,否则,按书名排序。这是我的问题,因为我不知道什么键发送和什么放在我的描述符(我甚至不确定是可能的)。
3) Sort by Volume Numbering IF it is part of a Saga, otherwise, sort by Book Title. Here is my problem, as I don't know what key to send and what to put in my descriptor (I'm not even sure it's possible).
NSSortDescriptor* thirdSort = [[SagaTomaisonOrBookTitleSortDescriptor alloc] initWithKey:@"self" ascending:YES];
到目前为止,我发现@self允许发送被查询的对象似乎不允许查询发送对象内的参数。作为参考,我尝试了一些代码:
So far, I've found that @"self" allows to send the object being queried but it doesn't seem to allow queries of parameters inside the sent object. For reference, there is some code I tried:
- (NSComparisonResult)compareObject:(id)object1 toObject:(id)object2
{
if (NULL_OBJECT([(Book*)object1 fromSaga]) && NULL_OBJECT([(Book*)object2 fromSaga])) {
return [super compareObject:[(Book*)object1 title] toObject:[(Book*)object2 title]];
}
if (NULL_OBJECT([(Book*)object1 fromSaga])) {
return NSOrderedDescending;
}
if (NULL_OBJECT([(Book*)object2 fromSaga])) {
return NSOrderedAscending;
}
return [super compareObject:[(Book*)object1 tomaison] toObject:[(Book*)object1 tomaison]];
}
有什么想法,我能做些什么?
Any idea what I can and should do ?
谢谢!
编辑:最后一行中有一个类型
there was a type in the last line
推荐答案
如果你不使用基于SQL的存储,你可以通过传递self作为你的key和比较:作为选择器,然后实现那个自定义选择器。也就是说,在你的书类上创建一个名为compare的方法,并且只使用它的所有逻辑,而不是使用多个排序描述符。
If you're not using an SQL-based store, you could do this by passing self as your key and compare: as the selector, then implement that custom selector. That is, make a method on your book class called compare: and just have it do all of your logic rather than using multiple sort descriptors.
这篇关于复杂对象上的自定义NSSortDescriptor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!