Os Dados Principais não podem resolver falhas quando o objeto tem o atributo "descrição"?
Código:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"A"
inManagedObjectContext:moc];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"id" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"somePredicate", someObject];
[fetchRequest setPredicate:predicate];
frc = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:moc
sectionNameKeyPath:@"recency"
cacheName:@"frc"];
[fetchRequest release];
frc.delegate = self;
NSError *error;
BOOL success = [frc performFetch:&error];
if (!success) {
NSLog(@"error: %@", error);
}
for (A *a in [frc fetchedObjects]) {
[someMutableArray addObject:a.b];
[someMutableArray addObject:a];
}
Modelo de dados:
A e B são entidades. A tem uma relação obrigatória um com B. B possui uma relação inversa opcional com muitos com A.
Acima em inglês:
Inicialize um NSFetchedResultsController para obter alguns dados para ativar uma visualização de tabela. Após a busca inicial, reserve os dados para algum processamento.
Agora, mais tarde, tento fazer isso:
id object = [someMutableArray objectAtIndex:someIndex];
NSLog(@"%@", object);
if ([object isMemberOfClass:[B class]]) {
someVar = object.propertyFromB; // problem
} else if ([object isMemberOfClass:[A class]]) {
someVar = object.propertyFromA;
}
Pergunta / problema: a linha indicada com "problema" trava. (EDIT: Veja abaixo a resolução, mas ainda gostaria de uma explicação.)
A chamada NSLog acima gera:
2010-01-30 14:47:14.433 app[22618:20b] <B: 0xf7f750> (entity: B; id: 0xf7ba70 <x-coredata://B01FEC86-14D6-4973-BFDB-EDE4AFD24FDC/B/p4> ; data: <fault>)
2010-01-30 14:47:14.438 app[22618:20b] <A: 0xf7e360> (entity: A; id: 0xf35820 <x-coredata://B01FEC86-14D6-4973-BFDB-EDE4AFD24FDC/A/p6> ; data: {
prop1 = value1;
prop2 = value2;
... etc ...
})
Ou seja, pela linha problemática, se o objeto era do tipo A, ele estava com falha e está disponível na memória, mas se for B, é uma falha.
Meu entendimento é que a linha "problema" deve disparar a falha e buscar os dados do armazenamento, mas isso não está acontecendo. Eu gostaria de entender / depurar o porquê. Eu tentei inserir chamadas willAccessKey / didAccessKey em torno disso. Também tentei definir setRelationshipKeyPathsForPrefetching: "b" na solicitação de busca. Nem funcionou.
Minha hipótese é que, como estou abusando um pouco dos resultados do NSFetchedRequestController, o mecanismo com falha fica confuso ao longo do caminho e não busca a falha quando deveria. Então, acho que uma maneira de força bruta seria criar uma nova solicitação de busca manual para buscar o objeto B relacionado no momento certo. Mas existe uma maneira melhor?
EDITAR:
O problema era que o objeto B tinha uma "descrição" de propriedade que eu havia definido, mas que colide com o nome interno do NSObject. O Xcode sempre me deu avisos, mas eu os ignorei porque pensei que a "propriedade / método interno da" descrição "é usada apenas para descarregar seqüências de caracteres no console e similares, e não no processamento interno.
O problema desapareceu depois que eu fiz uma nova versão do meu modelo, renomeando "descrição" para outra coisa. Todas as falhas começaram a funcionar como esperado.
Mas não entendo o que está acontecendo. O Core Data está usando o método "descrição" dos objetos para alguma introspecção interna?