2014-09-06 1 views
7

folgende NSSortDescriptor für Strings mit Core Data Gegeben:die Art und Weise steuern sortiert NSSortDescriptor Null Werte in Core Data

[NSSortDescriptor sortDescriptorWithKey:@"series" ascending:true selector:@selector(caseInsensitiveCompare:)] 

Die Ergebnisse sind korrekt alphabetisch aufsteigend geordnet. Jedoch in Fällen, in denen seriesnil, Strings mit nil Werte sind an der Spitze platziert, mit Nicht-Null-Werte danach sortiert werden, z:

[nil, nil, nil, A, B, C, D...] 

Gibt es eine Möglichkeit, dieses Verhalten zu kontrollieren? Core Data erlaubt keine benutzerdefinierten Selektoren. Hier ist eine ähnliche Frage zu mir (nicht Kerndaten der Einschränkung Adressierung, jedoch):

NSSortDescriptor and nil values

+0

Soweit ich graben habe. Ich denke, du kannst nicht. Sie müssen ein anderes mit keinen Nullwerten erstellen. – rptwsthi

Antwort

8

Während Sie nicht einen eigenen Selektor mit Core Data verwenden können, können Sie NSSortDescriptor Unterklasse das Standardverhalten zu ändern. So etwas sollte funktionieren:

#define NULL_OBJECT(a) ((a) == nil || [(a) isEqual:[NSNull null]]) 

@interface NilsLastSortDescriptor : NSSortDescriptor {} 
@end 

@implementation NilsLastSortDescriptor 

- (id)copyWithZone:(NSZone*)zone 
{ 
    return [[[self class] alloc] initWithKey:[self key] 
          ascending:[self ascending] selector:[self selector]]; 
} 

- (id)reversedSortDescriptor 
{ 
    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]]) && 
     NULL_OBJECT([object2 valueForKeyPath:[self key]])) 
     return NSOrderedSame; 

    if (NULL_OBJECT([object1 valueForKeyPath:[self key]])) 
     return NSOrderedDescending; 

    if (NULL_OBJECT([object2 valueForKeyPath:[self key]])) 
     return NSOrderedAscending; 

    return [super compareObject:object1 toObject:object2]; 
} 

@end 
+0

Das Makro 'NULL_OBJECT' wertet zweimal 'a' aus. Die Semantik ändert sich in diesem Fall nicht, weil das Argument keine Nebenwirkungen hat, aber das könnte man in Zukunft leicht vergessen. Es verdoppelt die Aufrufe von '-valueForKeyPath:' und '-key'. Besser, eine statische Inline-Funktion zu verwenden. Wenn Sie gerade dabei sind, können Sie diese Aufrufe auch nur einmal in '-compareObject: toObject:' vornehmen. Sortierungsdeskriptoren haben die Eigenschaft, dass sie häufig aufgerufen werden, daher ist Leistung wichtig. Schließlich ist "[NSNull null]" nachweislich ein Singleton, also können Sie einfach die Zeigergleichheit verwenden, um dies zu überprüfen. –

+0

Dieser Ansatz funktionierte bei Verwendung eines abgerufenen Ergebniscontrollers nicht. Ich vermute, dass in diesem Fall CoreData die Sortierdeskriptoren in SQL-Abfragen konvertiert und niemals compareObject aufruft: –

Verwandte Themen