3

初めての投稿ですので、頑張りますが規約を守れないかもしれませんがよろしくお願いします。私は常にSOの問題の解決策を見つけてきましたが、かなり複雑なCocoaの問題に完全に行き詰まっています。

CoreData オブジェクトのリストで複雑な並べ替えを実行しようとしています。Saga (最初の本とその続編) の一部である Book オブジェクトで構成されるカタログがあります。単純化された構造は次のようになります。

@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;

Book の CoreData データベースでクエリを実行しようとしています。

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:context];

そして、次の 3 つのステップで並べ替えが必要です。

1) 本のジャンルで並べ替えます (必要ないため、上記のコードには含まれていません)。これは次のように実行されます。

NSSortDescriptor* mainSort = [[NSSortDescriptor alloc] initWithKey:@"ofGenre.title" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];

2) 本が佐賀の一部である場合、佐賀のタイトルで並べ替える

NSSortDescriptor* secondarySort = [[SagaTitleSortDescriptor alloc] initWithKey:@"fromSaga" ascending:YES];

カスタムソート記述子は次のように定義されています。

#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) サガの一部である場合は巻番号で並べ替え、そうでない場合は本のタイトルで並べ替えます。これが私の問題です。送信するキーと記述子に何を入力するかわからないためです(それが可能かどうかさえわかりません)。

NSSortDescriptor* thirdSort = [[SagaTomaisonOrBookTitleSortDescriptor alloc] initWithKey:@"self" ascending:YES];  

これまでのところ、@"self" を使用すると、クエリ対象のオブジェクトを送信できますが、送信されたオブジェクト内のパラメーターのクエリは許可されていないようです。参考までに、私が試したいくつかのコードがあります:

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

私ができることとすべきことは何ですか?

ありがとう !

編集:最後の行にタイプがありました

4

1 に答える 1

1

SQL ベースのストアを使用していない場合は、キーとして self を渡し、セレクターとして compare: を渡して、そのカスタム セレクターを実装することでこれを行うことができます。つまり、book クラスに compare: というメソッドを作成し、複数のソート記述子を使用するのではなく、すべてのロジックを実行させるだけです。

于 2012-06-25T01:05:09.470 に答える