2009-05-23 6 views
6

J'ai une application Core Data. Dans le thread producteur, je tire des données d'un service Web et les stocke dans mon objet et appelle save. Mon objet consommateur est un contrôleur de vue de table qui affiche le même. Cependant, les application se bloque et je reçois NSFetchedResultsController Erreur: devrait trouver l'objet (entité: FeedEntry; id: 0xf46f40; données:) dans la section (null) pour la suppressionProblème de consommateur du producteur avec les données de base

sur la console. Quand je débogue, tout fonctionne bien. J'ai donc compris que c'était comme une question de course.

Comment ce genre de problème est-il résolu? Quelle est la meilleure façon de concevoir une application producteur-consommateur avec des données de base?

Répondre

16

Si vous ciblez Leopard ou plus tard, Apple vous facilite les choses.

Dans votre thread de création, créez un MOC avec le même PSC que le MOC dans votre thread principal. Vous pouvez extraire des objets de votre service Web dans ce fil de discussion, créer les nouveaux objets et les enregistrer normalement.

Dans votre thread consommateur, ajoutez votre contrôleur en tant qu'observateur pour NSManagedObjectContextDidSaveNotification. Votre rappel devrait ressembler à:

- (void) managedObjectContextDidSave:(NSNotification *)notification 
{ 
    NSManagedObjectContext *managedObjectContext = [notification object]; 
    if(managedObjectContext != self.managedObjectContext) 
    [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification]; 
} 

De cette façon, les objets enregistrés dans le fil de producteur sera automatiquement tiré dans votre fil à la consommation.

+1

Merci sbooth ... Votre réponse était parfait ... Pour d'autres, Pour vous abonner au NSManagedObjectContextDidSaveNotification, ajoutez le code suivant ... \t \t [[NSNotificationCenter defaultCenter] addObserver: appDelegate \t \t \t \t \t \t \t \t \t \t \t \t sélecteur: @selector (managedObjectContextDidSave :) \t \t \t \t \t \t \t \t \t \t \t \t \t Nom: NSManagedObjectContextDidSaveNotification \t \t \t \t \t \t \t \t \t \t \t \t objet: auto.managedObjectContext]; – Mugunth

+2

@Mugunth Kumar, puisqu'il vérifie dans quel contexte il est probable que vous devriez passer nil pour l'objet param, vous ne voulez pas observer le nouveau contexte créé pour le thread bg et pas le contexte du délégué de l'application. – marchinram

+0

Exactement ce que je cherchais. Merci. – JHollanti

0

Les données de base ne sont généralement pas sécurisées. Ma préférence serait de faire un minimum de travail sur le thread d'arrière-plan, et de transmettre les données nécessaires pour créer des entités de base de données au thread principal une fois que vous l'avez récupéré à partir de votre service Web. Cependant, jetez un oeil à this document. Il existe certaines stratégies pour utiliser les données de base sur les threads si nécessaire.

+0

"Les données de base ne sont généralement pas thread-safe" est plutôt trompeur. Si vous créez un contexte pour chaque thread (ou chaque opération, les contextes sont assez légers), le reste de la structure Core Data s'occupe de tout le reste (tout ce que vous avez à faire est de gérer NSManagedObjectContextDidSaveNotifications comme décrit ci-dessus). – hatfinch

+0

Je suis d'accord, c'est très trompeur. – JHollanti

Questions connexes