2012-10-22 8 views
6

In meinem Kerndatenmodell hat eine Person einen oder mehrere Cars, die durch die ungeordnete to-many Beziehung 'Cars' angegeben werden. Häufig muss ich die Autos einer Person abrufen, die von datePurchased bestellt werden, oder dateLastUsed.Abgerufene Eigenschaft in Core Data

Bis jetzt habe ich meine eigene Methode zu Person für carsByDatePurchased hinzugefügt. Dies verwendet einen Sortierungsdeskriptor, um das NSSet cars zu sortieren und ein NSArray zurückzugeben.

Könnte/sollte ich stattdessen eine abgerufene Eigenschaft dafür verwenden? Ich erlebe einen gewissen Performance-Overhead, indem ich jedes Mal, wenn ich die Autos in einer bestimmten Reihenfolge brauche, den Sortierungsdeskriptor benutze und dabei sogar mein eigenes Caching von carsByDatePurchased implementiere. Es sieht so aus, als ob die geholte Eigenschaft für mich zwischengespeichert wird - ist das korrekt?

Welche Beschränkungen hat eine abgerufene Eigenschaft gegenüber meiner eigenen Implementierung?

Und entscheidend, bleibt der Wert der abgerufenen Eigenschaft zwischen den Ausführungen bestehen? Wenn ich die abgerufene Eigenschaft aktualisiere und meinen Kontext speichere, wird der Wert für den nächsten Start der Anwendung gespeichert?

Antwort

1

Eine abgerufene Eigenschaft ist im Grunde eine Abrufanforderung. Ich weiß nicht, wie ich diesen Eigenschaften in der GUI Sortierdeskriptoren hinzufügen kann, aber ich kann mich irren. Aber warum erstellen Sie nicht einfach eine Fetch-Anfrage in Ihrer carsByDatePurchased-Methode und geben Sie eine Sortierung an? Sie gibt ein Array oder die Ergebnisse zurück (die Sie billig in ein NSOrderedSet mit copyItems: Flag auf Nein umbrechen können).

+0

Was ist der Unterschied zwischen dem Zugriff auf self.cars und dem Anwenden der Sortierung? Warum würde ich von einer anderen Abrufanforderung in cardsByDatePurchased profitieren, anstatt nur self.cars zu verwenden? –

+0

Da die Sortierung auf Datenbankebene statt nach einem Abruf aus der Datenbank durchgeführt wird. –

+0

Soll ich alle Autos holen und ein Prädikat verwenden, um sie auf Person == Selbst zu beschränken? Oder kann ich self.cars in irgendeiner Weise wiederverwenden? –

2

Wenn Sie etwas Leistung erzielen möchten, holen Sie mit einem NSFetchedResultsController und arbeiten mit einem Cache. Wenn Sie das nächste Mal denselben Abruf durchführen, wird der Abruf schneller. In Ihrem speziellen Namen müssen Sie Namen zwischenspeichern. Werfen Sie einen Blick auf den NSFetchedResultsController documentation.

+0

Aber würden die zwischengespeicherten Ergebnisse zwischen den Starts beibehalten? Das ist ein entscheidender Teil, nach dem ich suche. –

+0

Ja (Padding weil Antwort ist nicht lang genug) – J2theC

+0

Nun gut, gut. Dies könnte die Wunderwaffe sein. Ich werde das heute versuchen. Um es klar zu sagen, Sie schlagen vor, den NSFetchedResultsController * innerhalb * meiner cardsByDatePurchased-Methode zu verwenden? Diese Methode befiehlt zur Zeit self.cars und gibt das Array zurück - Sie sagen, sollten die Autos holen und sie mit dem Ergebnis-Controller * anstatt * von autos.self sortieren? –

4

Eine abgerufene Eigenschaft funktioniert, und tatsächlich habe ich sie in meinem eigenen Projekt mit einer Post-> Comment-Beziehung verwendet, die nach "date added index" sortiert werden muss.

Es gibt eine Reihe von Einschränkungen: Sie können im visuellen Editor keinen Sortierungsdeskriptor angeben und müssen ihn im Code angeben.

ich so etwas wie diese

// Find the fetched properties, and make them sorted... 
for (NSEntityDescription *entity in [_managedObjectModel entities]) 
{ 
    for (NSPropertyDescription *property in [entity properties]) 
    { 
     if ([property isKindOfClass:[NSFetchedPropertyDescription class]]) 
     { 
      NSFetchedPropertyDescription *fetchedProperty = (NSFetchedPropertyDescription *)property; 
      NSFetchRequest *fetchRequest = [fetchedProperty fetchRequest]; 

      // Only sort by name if the destination entity actually has a "index" field 
      if ([[[[fetchRequest entity] propertiesByName] allKeys] containsObject:@"index"]) 
      { 
       NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"index" 
                      ascending:YES]; 

       [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortByName]]; 
      } 
     } 
    } 
} 

In My Post Entität Ich habe eine hergeholt Eigenschaft "sortedComments", die definiert ist als:

post == $FETCH_SOURCE 

wo Beiträge eine to-many „Anmerkungen "Beziehung und Kommentare haben eine" Post "inverse

Im Gegensatz zu den anderen Antworten hier: Die Vorteile der Verwendung einer abgerufenen Eigenschaft wie folgt, ist CoreData kümmert sich um die Zwischenspeichern und Ungültigmachen des Caches als Kommentare für einen Post oder in der Tat ändert sich der Post, der sie besitzt.

0
AppDelegate *delegate = [UIApplication sharedApplication].delegate; 
NSManagedObjectContext *context = [delegate managedObjectContext]; 

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription 
           entityForName:@"DataRecord" inManagedObjectContext:context]; 
[fetchRequest setEntity:entity]; 
NSError *error; 
fetchedObjects = [context executeFetchRequest:fetchRequest error:&error]; 
for (NSManagedObject *obj in fetchedObjects) { 
    NSLog(@"Name: %@", [obj valueForKey:@"name"]); 
    NSLog(@"Info: %@", [obj valueForKey:@"info"]); 
    NSLog(@"Number: %@", [obj valueForKey:@"number"]); 
    NSLog(@"Create Date: %@", [obj valueForKey:@"createDate"]); 
    NSLog(@"Last Update: %@", [obj valueForKey:@"updateDate"]); 
} 
NSManagedObject *obj = [fetchedObjects objectAtIndex:0]; 
[self displayManagedObject:obj]; 
selectedObject = obj; 
+0

Während dieser Code die Frage beantworten kann, würde die Bereitstellung eines zusätzlichen Kontextes hinsichtlich dessen, wie und/oder warum er das Problem löst, den langfristigen Wert der Antwort verbessern. –

+0

Dieser Code ist nur zum Abrufen –

+2

Wenn es keine Antwort auf die Frage ist, sollte es nicht an erster Stelle sein. Bei Stack Overflow müssen Antworten eine Lösung für die Frage bereitstellen. –