/ / Core Data: uma busca tem que fazer uma viagem à loja persistente? - iphone, objective-c, ios, core-data

Core Data: uma busca tem que fazer uma viagem à loja persistente? - iphone, objective-c, ios, core-data

Diga eu faço isso:

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#
}

A busca no loop incorrerá em uma viagem para o armazenamento persistente toda vez? Ou aquelas buscas serão realizadas apenas no cache de linha do coredata?

EDITAR Eu escrevi um fragmento de código de teste: Você precisa criar uma entidade de dados core chamada "Person" e deve ter um atributo chamado "name", que é do tipo string.

use este código para preencher alguns dados:

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

perfil este dois métodos e você encontrará custos usingCoreData muito mais tempo do que 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]];
}
}
}

Respostas:

1 para resposta № 1

Acho que preciso responder a minha pergunta sozinho.

Eu testei e achei, toda vez que uma buscaExecutados, os dados do núcleo traduzirão o seu comando NSFetchRequest em SQL e invocarão uma consulta de base de dados, o resultado da consulta é primeiramente NSManagedObjectIDs, o cache é aplicado para obter o NSManagedObject de um NSManagedObjectID.

Em conclusão, ele armazena em cache o objeto, mas não armazena em cache o resultado da consulta.

Isso significa que você executa o mesmo NSFetchRequestpor 10 vezes, ele consultará sua loja persistente por 10 vezes, embora você receba 10 vezes o mesmo resultado. Portanto, em tal situação, a matriz de filtragem na memória terá um desempenho melhor do que a busca.


0 para resposta № 2

A busca virá do cache especificado quando disponível.

EDITAR: Aqui está um link para um ótimo tutorial que mostra como configurar um NSFetchedResultsController que usa um cache.

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