2010-02-02 4 views
1

Quels sont les pièges obscurs de l'utilisation des données de base et des threads? J'ai lu une grande partie de la documentation, et jusqu'à présent, je suis venu à travers ce qui suit soit dans la documentation ou par l'expérience douloureuse:Données de base et threads

  • Utilisez un nouveau NSManagedObjectContext pour chaque fil, mais un seul NSPersistentStoreCoordinator est suffisant pour la application entière
  • Avant d'envoyer un objet objectID de NSManagedObject au thread principal (ou à tout autre thread), assurez-vous que le contexte a été sauvegardé (ou, au minimum, ce n'était pas un objet nouvellement inséré mais pas encore enregistré) - sinon objectID sera en fait un identifiant temporaire et non persistant. Utilisez mergeChangesFromContextDidSaveNotification: pour détecter quand une sauvegarde se produit dans un autre thread et l'utiliser pour fusionner ces modifications avec le contexte du thread actuel.

Bonus question/observation: je fus amené à croire par le libellé de certains des documents que mergeChangesFromContextDidSaveNotification: est quelque chose que nécessaire par le thread principal pour fusionner les changements dans le contexte « principal » de threads de travail - mais je ne pense pas que c'est le cas.

J'ai configuré mon importateur pour créer des lots de données qui sont importés en utilisant une sous-classe d'un NSOperation qui possède son propre contexte. Les opérations sont chargées dans une file d'attente NSOperationQueue définie pour autoriser le nombre d'opérations simultanées par défaut. Il est donc possible que plusieurs lots d'importation soient exécutés en même temps. J'obtiens occasionnellement des erreurs et des exceptions de validation très étranges (comme essayer d'ajouter une relation nulle) et d'autres échecs que je n'avais jamais vus quand j'ai fait tous les mêmes choses sur le fil principal. Il m'est apparu (et peut-être que cela aurait dû être évident) que peut-être la fusion du contexte devait être faite pour tous les contextes dans chaque fil - pas seulement le «principal»! Je ne sais pas pourquoi je n'ai pas pensé à cela avant, mais je pense que cela a aidé. (Il n'a pas été testé assez bien pour que je sois sûr, cependant.) Dans tous les cas, est-il vrai que vous devez observer cette notification pour TOUS les threads d'importation qui peuvent travailler avec les mêmes jeux de données et ajouter/mettre à jour mêmes entités? Si c'est le cas, c'est encore un autre point critique, l'OMI, bien que je ne sois pas encore certain que cela fonctionnera. Étant donné le nombre de ceux-ci que j'ai rencontrés avec des données de base en général (et pas tous à propos de multi-threading), je me demande combien d'autres se cachent. Étant donné que le multi-thread se termine si souvent avec des bugs qui sont difficiles, voire impossibles à reproduire en raison des problèmes de timing, je me demandais si quelqu'un avait d'autres choses importantes qui me manquaient et auxquelles je devais m'occuper.

Répondre

2

Il y a toute une partie de la documentation consacrée au sujet Core Data and Threading.

Il n'est pas clair d'après votre série de problèmes ce qui n'est pas couvert par cette documentation.

+0

Eh bien, c'est bon à entendre. J'ai lu ces documents souvent; chaque fois que je les lis, je trouve de nouveaux petits détails qui me manquent. Les documents de base de données sont très denses et ont souvent des petites choses comme "oh, et notez que " qui inévitablement s'avère beaucoup plus important que le "oh btw au cas où vous étiez curieux ..." que le le libellé implique souvent (pour moi, de toute façon). Bien que j'imagine que si le document entier était en gras et mis en italique, ça n'aiderait pas grand chose, non plus ... :) – Sean