Je développe une application iPhone avec des données de base. Toutes les données utilisateur doivent être synchronisées avec nos serveurs. À cette fin, j'ai créé une sous-classe de sorcière Nsoperation charge de nouvelles données à partir de notre service Web et crée des objets gérés correspondants. Pour maintenir les relations entre eux, chaque objet est transmis avec une remoted (qui est la clé principale du serveur relationnel dB).
Disons qu'il y a deux objets gérés: Département <- >> Employé. La synchronisation fonctionne comme suit: p>
chargez tous les départements du serveur. Pour chaque département: Créez un objet de département et définissez sa remoted. P> LI>
chargez tous les employés du serveur. Pour chaque employé: Créez un objet employé, récupérez le service associé (par Rote Rote) et attribuez-le à l'employé. P> LI> OL>
La récupération d'un département conduit à l'exception suivante: p> L'exception n'est pas lancée à chaque fois. Déplacer le code sur le fil principal résout le problème. Je n'ai aucune idée de ce qui ne va pas. J'ai créé une nouvelle NsmanieDObjectContaxt dans le fil de synchronisation et j'ai passé tous les objets gérés par son NSManèdeObjectid. P> Toute pensée? P> P>
4 Réponses :
Off the Haut de ma tête: Le fil "Synchronisation" a-t-il ajouté de nouveaux objets à la collection du département tout en itérant sur le fil principal? p>
généralement, ce type d'exception se produit lorsque vous modifiez une collection en même temps que vous l'énumérez. Dans un scénario multi-threadé, cela peut également signifier que votre collection est énumérée et mise à jour simultanément sans synchronisation de thread correcte. P>
Pour moi, cela pourrait être la raison de ce genre de problème. Quel est le meilleur moyen de résoudre ces problèmes, vous avez une idée @octy?
Adeem, une bonne réponse à votre question a été fournie dans une discussion liée: Stackoverflow.com/questions/3364769/...
L'erreur "SOMECOLLECTION a été mutée tout en étant énuméré" est causée par la modification d'une collection mutable I.e. Le dictionnaire, le dictionnaire, le jeu, etc., tandis qu'un énumérateur en marche. Puisque vous ne pouvez pas énumérer une cible en mouvement, cela déclenche une erreur. p>
Dans ce cas, l'erreur est probablement causée par la tenue d'une relation d'employés d'une département sur le thread principal par exemple. Pour afficher dans une vue de table, tandis que le thread de fond ajoute simultanément des employés à la relation. p>
a travaillé autour de cela, vous devez geler l'interface utilisateur pendant que vous fusionnez les changements du fil d'arrière-plan. Pour les visualisations de la table, un contrôleur de résultats récupéré (NsfetchedResultSluTroller) avec des méthodes de délégation correctement implémentées dans le contrôleur de la TableView traitera le problème bien. p>
L'important est d'envoyer beginumdates code> à la tableView avant de fusionner les nouvelles données. Cela indiquera à la table que la structure de données sous-jacente est en cours de mutation afin qu'elle n'essaiera pas de redessiner. Lorsque la fusion est terminée, envoyez
endupdates code> à la tableView pour le faire afficher les nouvelles informations. p>
J'ai pensé à ce genre de problèmes et j'ai donc créé deux nsmanagedObjectContextes (un pour le fil principal et un pour le fil de synchronisation). N'est-ce pas une solution valide? J'utilise également NsfetchedResultController pour mes visualisations de table.
Oui, mais lorsque vous fusionnez les modifications apportées par les contextes, ils déclenchent la nécessité de mettre à jour pour refléter les modifications apportées à l'autre. Les méthodes de délégués FRC vous permettent de dire à l'interface utilisateur de geler pendant que ces changements sont traités. Ensuite, vous dégazez l'interface utilisateur et laissez-la montrer les mises à jour. Ce processus est généralement invisible pour l'utilisateur.
L'application se bloque avant de fusionner les changements dans le fil principal.
Je devrais ajouter que si vous ne gelez pas une vue de table, il peut essayer de redessiner pendant que ses données sont en flux. Cela le fait recevoir le mauvais nombre de sections et de lignes qui conduisent à des accidents intermittents.
L'accident se passe parce que vous recherchez des objets dans une relation pendant que vous êtes simultanément muté de l'ensemble qui contient cette relation. C'est probablement lorsque vous recherchez le département pour chaque employé pendant que vous ajoutez des employés aux relations des ministères. L'ajout d'un ministère à un employé ajoute automatiquement l'employé au département. Selon exactement comment vous codez tout cela, ils pourraient entrer en collision.
J'ai eu le même problème ... Il a été résolu parce que j'utilisais le gantedObjectContext créé sur le fil principal sur un fil d'arrière-plan. La solution consistait à créer un autre gestionnaire de gestionContext sur le fil d'arrière-plan et utilisez la persistance régulière ... Cela a fonctionné bien après ça! P>
Est-ce que tout fil de fond fonctionne? Stackoverflow.com/a/3448089/6839908 en fonction de la discussion là-bas, les contextes de fond doivent être créés sur les threads dans lesquels ils sera utilisé. Je suis un peu confus parce que le fil dans lequel le contexte sera utilisé n'existe pas encore lorsque nous voulons le créer, n'est-ce pas?
J'ai eu le même problème. Vous pouvez utiliser le serrure, déverrouillez un récepteur. J'ai résolu ce problème jusqu'à présent. P>