/ / Core Data: Muss ein Abruf eine Reise in einen dauerhaften Speicher unternehmen? - iPhone, Objective-C, iOS, Core-Daten

Core Data: Muss ein Fetch einen Trip in den persistenten Store machen? - iPhone, Ziel-C, IOS, Kerndaten

Sagen wir, ich mache das:

NSManagedObjectContext *context = #a managed object context";
NSString *entityName = #an entity name#;
NSFetchRequest *requestForAll = [NSFetchRequest requestWithEntityName:entityName];
NSArray *allObj = [context executeFetchRequest:requestForAll];

for (NSString *name in allNamesArray){
NSFetchRequest *requestForOne = [NSFetchRequest requestWithEntityName:entityName];
requestForOne.predicate = [NSPredicate predicateWithFormat:@"name == %@",name];
NSArray *ObjsWithName = [context executeFetchRequest:requestForOne];
#do some work with the obj#
}

Führt der Abruf in der Schleife jedes Mal zu einer Reise zum permanenten Speicher? Oder werden diese Abrufe nur im Zeilencache von coredata ausgeführt?

BEARBEITEN Ich habe ein Fragment des Testcodes geschrieben: Sie müssen eine zentrale Datenentität mit dem Namen "Person" erstellen und ein Attribut mit dem Namen "name" vom Typ "string" haben.

Verwenden Sie diesen Code, um einige Daten zu füllen:

self.array = @[@"alkjsdfkllaksjdf",@"asldjflkajdklsfjlk;aj",@"aflakjsdl;kfjalksdjfklajkldhkl;aj",@"aljdfkljalksdjfl;j" ,@"flajdl;kfjaklsdjflk;j",@"akldsjfklajdslkf",@"alkdjfkljaklsdjflkaj",@"alsdjflkajsdflj",@"adlkfjlkajsdfkljkla",@"alkdjfklajslkdfj"];

NSString *firstRunKey = @"oh its first run!";
NSString *firstRun = [[NSUserDefaults standardUserDefaults] objectForKey:firstRunKey];
if (!firstRun) {
for (NSString *name in self.array) {
Person *p = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
p.name = name;
}
}
[self.managedObjectContext save];
[[NSUserDefaults standardUserDefaults] setObject:firstRunKey forKey:firstRunKey];
[[NSUserDefaults standardUserDefaults] synchronize];

Profilieren Sie diese beiden Methoden und Sie werden feststellen, dass usingCoreData viel mehr Zeit kostet als usingFilterArray!

static int caseCount = 1000;
-(void)usingCoreData
{
NSLog(@"core data");
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"];
NSArray *allPersons = [self.managedObjectContext executeFetchRequest:request error:nil];

for (int i = 0; i < caseCount; i++){
for (NSString *name in self.array) {
request.predicate = [NSPredicate predicateWithFormat:@"name == %@",name];
NSArray *result = [self.managedObjectContext executeFetchRequest:request error:nil];
}
}
}

-(void)usingFilterArray
{
NSLog(@"filter array");
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"];
NSArray *allPersons = [self.managedObjectContext executeFetchRequest:request error:nil];

for (int i = 0; i < caseCount; i++){
for (NSString *name in self.array) {
NSArray *array = [allPersons filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"name == %@",name]];
}
}
}

Antworten:

1 für die Antwort № 1

Ich denke, ich muss meine Frage selbst beantworten.

Ich habe es getestet und jedes Mal einen Abruf gefundenausgeführt, werden Kerndaten Ihren NSFetchRequest in SQL-Befehl übersetzen und eine Datenbankabfrage aufrufen. Das Abfrageergebnis ist zunächst NSManagedObjectIDs. Das Caching wird angewendet, um das NSManagedObject von einer NSManagedObjectID abzurufen.

Abschließend wird das Objekt zwischengespeichert, das Abfrageergebnis jedoch nicht zwischengespeichert.

Das heißt, Sie führen denselben NSFetchRequest aus10-mal wird Ihr persistenter Speicher 10-mal abgefragt, obwohl Sie 10-mal das gleiche Ergebnis erhalten. In einer solchen Situation ist das Filtern des Arrays im Speicher besser als das Abrufen.


0 für die Antwort № 2

Der Abruf erfolgt aus dem angegebenen Cache, sofern verfügbar.

BEARBEITEN: Hier ist ein Link zu einem großartigen Tutorial, das zeigt, wie man eine NSFetchedResultsController das verwendet einen Cache.

http://www.raywenderlich.com/?p=999