2012-04-11 14 views
3

Ich habe eine Entität Tag mit Zeichenfolge Eigenschaft tagName. Ich ging, um alle Objekte in dieser Entität in eine NSFetchedResultsController zu holen, aber ich möchte Tag mit tagName "Main", das erste Objekt sein. Hier ist, was ich tue jetzt:Sortieren von Kerndaten Ergebnisse in NSFetchedResultsController

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription 
            entityForName:@"Tag" inManagedObjectContext:appDelegate.managedObjectContext]; 

[fetchRequest setEntity:entity]; 

NSSortDescriptor *lastDescriptor2 = 
[[[NSSortDescriptor alloc] initWithKey:@"tagName" ascending:NO comparator:^NSComparisonResult(NSString* tag1, NSString* tag2) { 
    NSLog(@"compare"); 
    if ([tag1 isEqualToString:@"main"]) return NSOrderedAscending; 
    if ([tag2 isEqualToString:@"main"]) return NSOrderedDescending; 
    return [tag1 compare:tag2]; 
}] autorelease]; 

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:lastDescriptor2]]; 
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:nil cacheName:nil]; 
self.fetchedResultsController = theFetchedResultsController; 
self.fetchedResultsController.delegate=self; 

if (![[self fetchedResultsController] performFetch:&error]) { 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
} 

Dieser Code in meiner viewDidLoad Methode aufgerufen wird, und nur einmal aufgerufen wird. Beim ersten Aufruf wird der sortDescriptor aus irgendeinem Grund nicht verwendet - er wird nicht aufgerufen (die NSLog-Anweisung wird ebenfalls nicht angezeigt). Meine Ergebnisse werden ausschließlich basierend auf dem Wert BOOL zurückgegeben, den ich für ascending angegeben habe - der Block wird ignoriert.

Aber wenn ich ein neues Tag Objekt in die MOC und die NSFetchedResultsController Update Delegatmethoden genannt einfügen, wird die tatsächliche SortDescriptor angelegt und die NSLog(@"compare") erscheint schließlich, aber nur, wenn ich machen Aktualisierungen der Objekte! Egal, was ich versucht habe, ich kann nicht die Art auf den ersten Abruf anwenden.

Irgendwelche Ideen?

+0

Mohabitar, Haben Sie versucht, einen Standardsortierdeskriptor anstelle von einem mit einem kundenspezifischen Komparator zu verwenden? Ich sage das, weil es einige ungerade Regeln gibt, welche Arten von Operationen tatsächlich mit einem Abruf in den Speicher angewendet werden können. Außerdem schlage ich vor, dass Sie Ihre Tests nur auf NSFetchRequest isolieren. Der Ergebniscontroller wird Rauschen hinzugefügt. IOW, stellen Sie sicher, dass der Abruf funktioniert. Dann mach dir Sorgen, es anzuzeigen. Andrew – adonoho

+0

Ya alles funktioniert ordnungsgemäß mit einem normalen Sortierungsdeskriptor. Der Abruf wird ausgeführt. Meine Ergebnisse werden sogar alphabetisch mit diesem Sortierdeskriptor oben abgerufen, so dass alles funktioniert. Und ich habe diesen genauen Sortierungsdeskriptor für eine normale Abrufanforderung ohne NSFetchedResultsController ausprobiert, und es funktionierte einwandfrei. Es ist nur der NSFetchedResultsController, der mir Probleme gibt. – Snowman

Antwort

1

Wie Sie wahrscheinlich an einem oder anderen Punkt gesehen haben, schlägt die Abrufanforderung fehl, wenn das Prädikat, das Sie an NSFetchRequest übergeben, ein Blockprädikat ist. Dies geschieht, weil CoreData Ihr Prädikat in SQL übersetzen muss, damit es gegen die Datenbank ausgeführt werden kann. Das Ergebnis ist, dass ein Prädikat niemals tatsächlich mit den Objekten verglichen wird, die sich aus der Abrufanforderung ergeben.

Das Gleiche gilt für Sortierdeskriptoren. Die Abrufanforderung führt keinen Vergleich mit den Objekten durch, wenn der Abruf ausgeführt wird. Es wird als Teil von SQL übergeben.

Sie beschreiben auch eine interessante Ausnahme zu den oben beschriebenen Regeln. Wenn Sie über einen vorhandenen NSFetchedResultsController verfügen und ein Objekt zu NSManagedObjectContext hinzufügen, wird der NSFetchedResultsController aktualisiert, indem das NSPredicate und der NSSortDescriptor für das Objekt ausgewertet werden, anstatt sie in SQL zu konvertieren.

Verwandte Themen