EDIT Merci à la publication de Matt, je comprends maintenant que je ne devrais pas essayer d'accéder à «commencé» comme un tableau. Cependant, si c'est le cas, j'aimerais savoir pourquoi ce code semble fonctionner ailleurs. Il me semble encore que cela devrait être "l'un ou l'autre". Ça devrait marcher ou ça ne devrait pas marcher.ExecuteFetchRequest lançant une exception par intermittence avec les mêmes paramètres. "pas la valeur clé codage-conforme pour la clé"
ORIGINAL J'utilise la même demande de récupération dans différentes parties de mon code pour trouver le plus récent jeu:
Game *lastGame = [[[CoreDataAccess managedObjectContext] fetchObjectsForEntityName:@"Game" withPredicate:@"started == [email protected]"] anyObject];
« Game » est un NSManagedObject et « commencé » est un attribut de date . 'started' est défini exactement une fois par objet dans awakeFromInsert. Il n'est jamais changé après cela. Le jeu n'est jamais directement instancié, mais il a trois sous-classes. J'ai essayé de rendre le jeu à la fois abstrait et concret, mais aucun n'a d'effet sur ce problème.
J'utilise une catégorie NSManagedObjectContext pour effectuer l'extraction, comme indiqué sur le cacao avec amour ici http://cocoawithlove.com/2008/03/core-data-one-line-fetch.html.
L'erreur que je reçois est la suivante:
Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. [<__NSDate 0xebb1130> valueForUndefinedKey:]: this class is not key value coding-compliant for the key @max. with userInfo {
NSTargetObjectUserInfoKey = "2010-11-06 11:16:53 GMT";
NSUnknownUserInfoKey = "@max";
}
Il me semble que le prédicat peut essayer d'appliquer @max à un seul NSDate, au lieu de tous les « commencé » des attributs dans tous les jeux. Je ne suis pas sûr cependant. Je ne suis pas très bon avec les prédicats, et il m'a fallu beaucoup d'essais et d'erreurs pour faire celui-ci. Je ne comprends pas comment exactement le même fetch peut avoir des erreurs dans différents endroits, cependant.
La récupération ne fait pas partie d'un NSFetchedResultsController, mais j'utilise un fetchedResultsController dans la classe où j'obtiens l'erreur. Par exemple:
- (void)configureCell:(UITableViewCell*)cell atIndexPath:(NSIndexPath*)indexPath{
Game *game = [self.frc objectAtIndexPath:indexPath];
Game *lastGame = [[[CoreDataAccess managedObjectContext] fetchObjectsForEntityName:@"Game" withPredicate:@"started == [email protected]"] anyObject]; // Sometimes we get past this line, sometimes we don't...
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"EEE, MMM d, yyyy h:mm a"];
if (game != lastGame)
cell.detailTextLabel.text = [format stringFromDate:game.started];
else
cell.detailTextLabel.text = @"In Progress";
[format release];
...
}
et aussi ici:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
Game *lastGame = [[[CoreDataAccess managedObjectContext] fetchObjectsForEntityName:@"Game" withPredicate:@"started == [email protected]"] anyObject];
if (lastGame == [frc objectAtIndexPath:indexPath])
return NO;
return YES;
}
Cette fetch exacte est effectuée à plusieurs reprises dans plusieurs endroits, par exemple au démarrage, mais il se bloque dans une seule classe. Comme je l'ai dit, il est intermittent, mais il semble que ce soit un jour après que je crée un nouvel objet Game. Le jeu est créé dans un onglet, et le code ci-dessus provient d'un deuxième onglet qui montre l'histoire.
J'ai vu une erreur similaire here. Dans ce cas, le problème a été résolu en redémarrant l'ordinateur, ce qui a finalement permis à XCode de réaliser que l'attribut avait été supprimé du modèle. J'ai essayé cela, et je suis toujours confronté au problème. J'ai également essayé de supprimer et de recréer l'attribut 'started' dans le modèle. J'ai également lu le Guide de dépannage des données de base, mais je n'ai pas trouvé d'aide non plus.
Matt, Merci pour votre réponse, et aussi pour votre super site! C'est très utile pour moi de comprendre comment les prédicats devraient fonctionner. En outre, je comprends parfaitement que je pourrais récupérer tous les jeux en tant que tableau trié et prendre la première valeur. (Bien que je ne me sois pas rendu compte que je pouvais limiter mon fetch à un résultat!) Je suppose que la racine de ma question était, cependant, pourquoi mon fetch fonctionne-t-il parfois? J'utilise le même code dans applicationDidFinishLaunching et j'utilise isKindOfClass pour charger la vue appropriée, et cela fonctionne, même si, si je vous ai bien compris, cela ne devrait pas être le cas. Une idée pourquoi? – arsenius