Question

J'utilise un NSFetchedResultsController pour gérer l'affichage des objets gérés récupérés dans une vue de table qui a une section. La table est vide en début et l'utilisateur peut ajouter de nouvelles entités à l'aide de l'interface utilisateur. En l'état actuel, le programme fonctionne toujours lors de l'ajout de la première entité, et se bloque toujours lors de l'ajout d'une seconde. Il n'y a parfois pas d'erreur présenté lors de l'accident et d'autres fois il y a des erreurs de types différents (certains ont inclus ci-dessous). Grâce à des instructions et traçage je vois que le programme se bloque juste après controllerWillChangeContent délégué du NSFetchResultsController (qui appelle [self.tableView beginUpdates];) sorties de méthode, mais avant toute autre méthode dans mon code est appelé. Voici quelques-unes des parties relavant de mon code. Configuration du NSFetchedResultsController:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Beer"
                                    inManagedObjectContext:self.managedObjectContext]];

// Configure request's entity and predicate
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptor release];
[sortDescriptors release];

NSString *expression = [NSString stringWithFormat:@"brewery.name LIKE \"%@\"", self.brewery.name];
NSPredicate *predicate = [NSPredicate predicateWithFormat:expression];
[fetchRequest setPredicate:predicate];
self.resultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                                             managedObjectContext:self.managedObjectContext
                                                               sectionNameKeyPath:nil
                                                                        cacheName:nil];
self.resultsController.delegate = self;
[fetchRequest release];

NSError *error = nil;
BOOL success = [resultsController performFetch:&error];
if (!success) {
    NSLog(@"Error fetching request %@", [error localizedDescription]);
}

Ajout d'une nouvelle entité:

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Beer" inManagedObjectContext:self.managedObjectContext];
Beer *beer = [[Beer alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext];
beer.name = beerName;
beer.brewery = self.brewery;

J'ai vu les avertissements dans la documentation au sujet des problèmes d'affichage des tables avec une section, et je l'ai utilisé la solution d'Apple pour que sans succès. Ces méthodes ne sont pas obtenir appelé avant l'accident de toute façon.

Certaines des erreurs que j'ai reçues:

Serious application error.  Exception was caught during Core Data change processing: *** -[NSCFString compareObject:toObject:]: unrecognized selector sent to instance 0x4e808c0 with userInfo (null)
Serious application error.  Exception was caught during Core Data change processing: *** -[CALayer compareObject:toObject:]: unrecognized selector sent to instance 0x4e53b80 with userInfo (null)
Serious application error.  Exception was caught during Core Data change processing: *** -[UITextTapRecognizer controllerWillChangeContent:]: unrecognized selector sent to instance 0x4ca5d70 with userInfo (null)
Serious application error.  Exception was caught during Core Data change processing: *** -[CALayer controllerWillChangeContent:]: unrecognized selector sent to instance 0x4e271a0 with userInfo (null)
Serious application error.  Exception was caught during Core Data change processing: *** -[NSCFNumber countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0x4c96ee0 with userInfo (null)

Comme vous pouvez le voir, les erreurs (quand on a été présenté) ne sont pas compatibles, même si aucune modification du code a été fait.

Quelqu'un peut-il comprendre ce que je fais mal?

Était-ce utile?

La solution

Vos erreurs incohérentes indiquent un problème possible sur la libération. D'autant plus que la modification de vos délégués de recharger uniquement les données rend la question disparaître. Personnellement, j'investir le temps de résoudre le problème plutôt que de coder autour comme vous ayant certainement un problème de code là que montrera probablement plus tard ailleurs.

Je ferais ce qui suit:

  1. Activer NSZombie
  2. Ajoutez un point d'arrêt pour objc_exception_throw
  3. Exécuter dans le débogueur

Lorsque l'exception se produit, regardez l'adresse de mémoire et voir ce qui est accessible et où. Cela permettra d'isoler le problème et vous dire ce qui se passe. Il serait également utile, si cela ne révèle pas le problème, d'afficher vos méthodes de délégué de NSFetchedResultsController pour que je puisse voir s'il y a quelque chose d'étrange en eux.

Best pour mettre à jour la question initiale avec les informations supplémentaires.

Autres conseils

Votre code pour créer de nouvelles entités est tout bizarre. Qu'en est-il en utilisant ceci:

Beer* beer = [NSEntityDescription insertNewObjectForEntityForName: @"Beer" 
    inManagedObjectContext: self.managedObjectContext];
beer.name = @"Grolsch";

, vous n'êtes pas non plus NSManagedObjectContext#save: appelez. Mais peut-être que vous faites que dans une partie de votre code que vous avez maintenant montrer?

Alors que je ne résout pas ce problème particulier, je pris à l'écriture de la classe qui a donné le la fonctionnalité que je veux et ne cause pas le problème se pose une approche légèrement différente. J'utilise toujours NSFetchedResultsController, mais plutôt que de mettre en œuvre les quatre méthodes de délégués, je ne fais que controllerDidChangeContent :, qui appelle la mise en œuvre juste [tableView reloadData].

Ceci est la mise en œuvre qui est inclus dans la classe RootViewController si vous créez une nouvelle application de navigation dans XCode qui utilise les données de base pour le stockage. Vous perdez probablement un certain contrôle sur des animations modifier la table, mais il est beaucoup plus simple et fonctionne très bien pour mes besoins.

J'ai eu un bug similaire récemment - votre problème est avec plus de libérer, en particulier:

[sortDescriptors release];

Vous obtenez le sortDescriptors objet de

[NSArray arrayWithObjects:sortDescriptor, nil];

qui n'a pas « alloc », « copie » ou « nouveau », il retourne un objet autoreleased. Parce que vous relâchez tôt, vous obtenez deux endroits où vous pouvez tomber en panne - lorsque le NSFetchRequest utilise, et quand il est libéré par la piscine. Voir le guide de gestion de la mémoire href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html" pour plus de détails .

Ceci est un ancien mais au profit d'autres ayant le même problème, je l'ai passé des heures à essayer de comprendre ce qui se passait et ont finalement trouvé un problème avec mon descripteur de tri qui a été à l'origine de ces plantages aléatoires.

Les messages d'erreur varient, mais étaient principalement liés à un compareObject: sélecteur toObject comme ci-dessous

.

- [_ NSCFSet compareObject: toObject:]: sélecteur non reconnu envoyé à l'instance - [ _NSCFString compareObject: toObject:] sélecteur non reconnu envoyé à l'instance

Ma suggestion est d'essayer d'éliminer tous les descripteurs de tri et prédicats de votre code, puis les ajouter un par un pour trouver où est le problème.

Bonne chance! Rog

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top