Pergunta

Eu tenho duas entidades: paciente e trabalho. O paciente tem um relacionamento muito para o trabalho chamado 'empregos' e o trabalho tem um relacionamento para um com o paciente chamado 'paciente'. Job tem atributos chamados 'DUDETE' (DATA) e 'Concluído' (Bool) e o paciente tem atributos 'FirstName' e 'LastName' (ambas as cordas).

Estou tentando criar uma solicitação de busca / predicado para o meu NSFetchedResultScontroller de que pegamos todos os trabalhos que não foram concluídos (ou seja, concluído == não) e a seccionem pelo nome do paciente. Aqui está o meu código:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Job" inManagedObjectContext:moc];
[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(completed == NO)"];
[fetchRequest setPredicate:predicate];

NSSortDescriptor *patientDescriptor = [[NSSortDescriptor alloc] initWithKey:@"patient" ascending:YES];
NSSortDescriptor *dueDateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"dueDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:patientDescriptor, dueDateDescriptor, nil];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:moc sectionNameKeyPath:@"patient" cacheName:@"Jobs"];

Aqui está o meu método TitleFeHeaderInsection:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:section];
NSString *firstName = [[(Job *)[fetchedResultsController objectAtIndexPath:indexPath] patient] firstName];
NSString *lastName = [[(Job *)[fetchedResultsController objectAtIndexPath:indexPath] patient] lastName];

return [NSString stringWithFormat:@"%@ %@", firstName, lastName];

Isso não parece funcionar. Estou fazendo isso da maneira errada?

Foi útil?

Solução

Primeiro, você parece não anexar os SortDescriptors a FetchRequests. Isso pode ou não estar conectado ao problema.

Segundo, você pode fazer isso de uma maneira mais fácil. Faça assim:

sectionNameKeyPath:@"patient.name"

"Nome" deve ser uma propriedade ou método do objeto do paciente. Uma maneira fácil de implementar isso seria ter um método de categoria no paciente:

- (NSString *)name {
    return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}

Na verdade, você não pode alcançar seu objetivo com algo tão simples assim, leia a resposta de Mzarra para a resposta correta. NSFetchedResultScontroller tem esse comentário crítico:

Se o controlador gerar seções, o primeiro descritor de classificação na matriz será usado para agrupar os objetos nas seções; Sua chave deve ser a mesma que a seção NameKeypath ou a ordem relativa usando sua chave deve corresponder a que o uso da SeçãoNameKeypath.

Mas você não pode classificar os resultados de uma chamada de método, precisará de uma propriedade do objeto. Portanto, sua melhor aposta é provavelmente ter uma propriedade "nome" em "paciente" e usar essa propriedade para classificar e seção nomeKeypath.

Outras dicas

Como não está funcionando? Ajuda a descrever quais resultados você está vendo.

Você não está adicionando seus descritores de classificação ao seu NSFetchRequest, pelo menos na amostra que você forneceu.

Seus descritores de classificação são ineficazes. Parece que Patient é um relacionamento tão classificado contra o relacionamento não funcionará. Você gostaria de fazer um tipo como o seguinte:

NSSortDescriptor *lastNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"patient.lastName" ascending:YES];
NSSortDescriptor *firstNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"patient.firstName" ascending:YES];
NSSortDescriptor *dueDateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"dueDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: lastNameDescriptor, firstNameDescriptor, dueDateDescriptor, nil];

[fetchRequest setSortDescriptors:sortDescriptors];

[lastNameDescriptor release], lastNameDescriptor = nil;
[firstNameDescriptor release], firstNameDescriptor = nil;
[dueDateDescriptor release], dueDateDescriptor = nil;

Você faz não precisa lançar [fetchedResultsController objectAtIndexPath:indexPath] à medida que retorna ID.

O que você está voltando da chamada para [fetchedResultsController objectAtIndexPath:indexPath]? Coloque um ponto de interrupção aqui e verifique o valor e verifique se você está recuperando um NSManagedObject em vez de nil. Colocar um ponto de interrupção nesse método também confirmará que você está sendo chamado.

Seu segundo nome não funcionará como mencionado acima. Você provavelmente quer defini -lo como @"patient.lastName" para que ele corresponda ao tipo inicial que descrevi acima.

Sua -tableView: titleForHeaderInSection: deve estar acessando o cache fornecido pelo NSFetchedResultsController ao invés de assumindo Que haverá uma fileira na seção:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
{
    id sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo name];
}

Finalmente, se você deseja que a seção exiba o formato "LastName, FirstName", então você precisará criar um não-transitório propriedade de valor derivado em seu Patient entidade que é o fullName para que você possa criar seu cache com base nele. Esse valor derivado precisaria ser atualizado sempre que o primeiro nome ou sobrenome fossem alterados.

Além de não atribuir seus SortDescriptores ao seu FetchRequest, acredito que você tem um problema com seu predicado. Como você está lidando com os dados principais, o valor booleano do seu atributo "concluído" é armazenado em uma instância do NSNumber. Algo como o predicado abaixo seria melhor:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"completed = %@", [NSNumber numberWithBool:NO]];
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top