Pergunta

Eu tenho um "Song" entidade e uma entidade "Tag" e eles têm muitos para muitos relação entre eles. Uma canção pode ter várias tags e uma tag pode ser aplicado a várias músicas.

Quero verificar se uma música tem uma determinada marca associada a ele. Se a música tem o Tag associted com ele, eu quero mostrar uma marca na exibição de tabela.

Para uma lógica semelhante, em "TaggedLocations" da Apple código de exemplo, a seguinte verificação é feita para verificar a presença do relacionamento.

if ([event.tags containsObject:tag]) {
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
}   

Isto pode ser ineficiente se há um grande número de marcas no banco de dados como este irá buscar todos eles na memória. Por favor me corrijam se eu estiver errado aqui.

Existe uma maneira mais eficiente para verificar se a canção é associado com uma determinada marca, em vez de check-in Song.Tags?

Foi útil?

Solução

É realmente muito fácil de fazer, se completamente indocumentados. Você deseja criar um pedido buscar com um predicado que tem uma operação de conjunto. Se imaginarmos que o seu modelo de Tag tem uma propriedade chamada tagValue, o predicado que importa é "QUALQUER tags.tagValue == 'footag'"

NSString *tagSearch = @"footag";

// However you get your NSManagedObjectContext.  If you use template code, it's from
// the UIApplicationDelegate
NSManagedObjectContext *context = [delegate managedObjectContext];

// Is there no shortcut for this?  Maybe not, seems to be per context...
NSEntityDescription *songEntity = [NSEntityDescription entityForName:@"Song" inManagedObjectContext:context];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:songEntity];

// The request looks for this a group with the supplied name
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagValue == %@", tagSearch];
[request setPredicate:predicate];

NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];

[request release];

Outras dicas

Você está correto, usando esse código irá recuperar todo o conjunto e a comparação objeto pode ser bastante complexo, dependendo de quantas propriedades e relacionamento são parte da entidade do objeto.

De qualquer forma, você não pode evitar uma comparação conjunto para a inclusão. Provavelmente, o melhor que você pode fazer é evitar buscar todas as propriedades / relacionamentos, pedindo Core Data para recuperar NSManagedObjectID apenas objetos.

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Tag" inManagedObjectContext:[self managedObjectContext]]]; 
[fetchRequest setResultType:NSManagedObjectIDResultType];
objetos

NSManagedObjectID são garantidos para ser único, portanto, você pode seguramente usá-los para verificar se há inclusão set. Isso deve ser muito mais eficiente para uma perspectiva de desempenho.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top