7
votes

Données de base: Résolvez une erreur Exc_Bad_Access étrange

Je suis confronté à un problème vraiment étrange avec les données de base. Décrivons-le:

Définitions h3>

Disons que j'ai deux modèles, Modela code> et Modelb code>. Dans le modèle de données modela code> a une référence à modelb code> en tant qu'association un à plusieurs, et, par conséquent, Modelb code> a un un à un Association avec Modela CODE>. P>

MISE UPDATE H3>

Lorsque l'application se lance (en particulier au premier lancement), ou lorsque l'utilisateur demande, je dois créer ou mettre à jour tout Les instances code> Modelb code> pour chaque Modela code> instance. Modela CODE> Les instances sont prédéterminées. Pour chaque Modela code> instance, j'ai environ 200 instances de Modelb code>. P>

J'utilise un code comme celui-ci: p>

#0  0x313f1460 in __CFBasicHashAddValue ()
#1  0x3133fff8 in CFBasicHashAddValue ()
#2  0x31344162 in CFSetAddValue ()
#3  0x31351012 in -[__NSCFSet addObject:] ()
#4  0x3514211a in _PFFastMOCObjectWillChange ()
#5  0x3512ed46 in _PF_ManagedObject_WillChangeValueForKeyIndex ()
#6  0x35132e7e in _sharedIMPL_setvfk_core ()
#7  0x3513316a in _svfk_2 ()
#8  0x0003b750 in -[_TassoStorico setValoreValue:] (self=0x6d97bf0, _cmd=0x49064, value_=1.02600002) at _TassoStorico.m:87
#9  0x0001b62e in -[EuriborParser(hidden) readStoricoForzato] (self=0x74200d0, _cmd=0x48ff7) at EuriborParser.m:236
#10 0x31349f02 in -[NSObject(NSObject) performSelector:withObject:] ()
#11 0x000441c4 in -[MBProgressHUD launchExecution] (self=0x90a6ff0, _cmd=0x4b83f) at MBProgressHUD.m:482
#12 0x352b3388 in -[NSThread main] ()
#13 0x353255cc in __NSThread__main__ ()
#14 0x34e20310 in _pthread_start ()
#15 0x34e21bbc in thread_start ()


15 commentaires

Pourriez-vous poster la trace de la pile d'un crash?


Je cherche juste l'exception à se produire ...


Je ne reçois pas une description particulière dans la console. Devrais-je chercher quelque chose d'autre?


Vous pouvez taper bt dans la console gdb pour obtenir le Backtrace , ce qui est similaire à ce que vous obtenez dans un rapport d'accident. exc_bad_access est une erreur générique qui signifie simplement que vous avez accès à une adresse de mémoire protégée, la plupart du temps un objet publié. Backtrace peut aider à comprendre où votre erreur s'est produite.


Si vous avez un NSException ou nserror , à la recherche de son userinfo Propriété Souvent fournit plus de détails sur ce qui se passe précisément . Vous pouvez aussi regarder cela également avec la console GDB: po [e userinfo]


Je viens d'ajouter une rare exception dans la question. Je vais essayer d'obtenir le habituel, si possible ...


On dirait que vous avez inséré dans nsmanagedObjectContext a nil entrée ... hmmm bizarre. Peut-être que votre contexte devrait-être être synchronisé plus tôt.


Cela se produit au chargement de l'application. Le contexte a été récemment créé ... et le fait étrange est que l'exception se produit lorsque je crée un nouvel objet ... je vais essayer de forcer le contexte à synchroniser juste au début de tout.


Vous pouvez voir la trace de la pile d'exception dans la question (modifier 2)


Regardez développeur.apple.com / Bibliothèque / iOS / # documentation / cacao / référencée CE / ... Si vous n'avez pas besoin du non-introduisant, peut-être la définir à NIL, aiderait ... - (vide) PROCESSPENDANGES Cette méthode cause Modifications apportées à des objets gérés enregistrés à enregistrer avec le gestionnaire d'annulation. Pas une solution, une solution de contournement.


Est _tasostorico.m: 87 == modèle.value = [Numéro de Number Numérovithdouble: myvalue]; ? Sinon, quelle contient cette ligne?


Une autre idée, on dirait que vous utilisez mbprogresshud , je suppose que votre code est déclenché à partir d'un rappel d'animation, à partir de la mémoire, je pense que Coredata n'est pas en sécurité multiple. Essayez de ne pas faire cela à partir de MbProgresshud ou essayez d'utiliser performselectoronmainthread peut-être?


Oui, c'est la ligne qui génère l'exception. En fait, j'appelle ces méthodes à partir d'un fil séparé, car l'ensemble du processus est assez long et je dois montrer à l'utilisateur un statut de progression (je le fais à la fois via MbProgresshud via un contrôleur de vue personnalisé)


Voir mon commentaire précédent sur Multi-threading ... presque parier que c'est ça :)


Ok, je vais essayer de suivre votre suggestion. Il sera assez long pour refroidir tout le code pour éviter les appels multi-threading sur CoreData, donc je ne peux donc pas vous dire maintenant si cela résout le problème. Vous pouvez également ajouter une réponse à cette question. Je vais l'accepter au cas où il résoudra la question. Merci!


4 Réponses :


10
votes

Coredata n'est pas du fil de sécurité; On dirait que c'est votre problème, essayez de regarder ce So question


3 commentaires

Apparemment, en utilisant un nsmanagedObjectContext dans le thread résolu le problème. Comme il est assez aléatoire, je dois faire des tests pour assurer que cela fonctionne correctement.


Vous ne pouvez utiliser un contexte que sur un fil lorsque le contexte a été créé sur ce fil. La pratique normale consiste à créer un deuxième contexte sur un fil d'arrière-plan pour des opérations intensives ou lentes, puis à fusionner le contexte d'arrière-plan et au premier plan lorsque l'opération de fond se termine.


Qu'est-ce que ça veut dire? Quel est un exemple de quelque chose qui est le fil-faire?



0
votes

Ces deux lignes sont redondantes et éventuellement dangereuses:

model.modelA = modelA;


2 commentaires

J'utilise habituellement un seul des deux appels. C'est un test que j'ai fait, mais je ne change pas l'exception. Le problème était celui qui a été déclaré par @vincent.


Vous avez raison que c'est une redondance, mais je ne pense pas que ce soit dangereux. Aussi, avez-vous voulu dire "la seconde de ces deux lignes est redondante"?



5
votes

J'ai eu un problème similaire (ea_bad_access sur [GestionEdContext Enregistrer]) causée par un KeyValueueobserver qui n'avait pas été supprimé quand il aurait dû être. Il était assez difficile de suivre. Cela signifiait que je recevais ce genre de comportement, même avec Arc.


1 commentaires

J'ai regardé partout et n'a rien trouvé. Tu as sauvé mon cul!



2
votes

Réinitialiser le contexte de votre objet géré après une migration de magasin persistante

J'ai eu des problèmes similaires. Je travaille aussi avec quelques threads et j'utilise MigratePersistTentStore: Tourl: Options: WithType: Erreur: Fonction.

Dans mon cas, l'erreur est arrivée juste après une migration dans un autre fil. Je pensais que mes problèmes étaient liés à thread, alors j'ai commencé à doubler sur la sécurité de thread-sécurité dans mon code, mais en réalité un seul appel à ManagedObjectContext.Reset () Avant Faire toutes les opérations ultérieures sur les objets dans le contexte de l'objet géré résolu toutes les questions.

Comportement de données de base

assez étrangement existantObjectwithid: erreur: me donnait toujours une référence à un objet non existant, de sorte que j'avais accès à des objets inexistants et recevant des objets inexistants et recevant exc_bad_access . Après avoir réinitialisé le contexte, la fonction a exposé le comportement correct.


0 commentaires