Wir haben versucht, ein Core Data Multiple Context/Threading-Problem zu debuggen, bei dem das Zusammenführen einer Core Data-Save-Benachrichtigung in unserem Hauptthread NSManagedObjectContext
sporadisch die App abstürzt. Das stürzt ~ 2% unserer App-Sitzungen ab und wir wissen nicht, wie wir das lösen können. Wir würden uns über jegliche Hinweise oder allgemeinen Ratschläge, die möglicherweise zu diesem Absturz führen könnten, sehr freuen.EXC_BAD_ACCESS on mergeChangesFromContextDidSaveNotification
Wir haben ein Core Data-Setup, das wie folgt aussieht:
N. B. Dies ist der Standard Core Data-Stack in magischen Rekord v2.3 von erstellt [MagicalRecord setupAutoMigratingCoreDataStack]
Dies ist das Szenario, in dem unsere App abstürzt: ist
- HTTP-Anforderung zurückgibt JSON
- JSON analysiert in
NSManagedObject
s (einige neue Einheiten, einige aktualisierte Entitäten) Kontext auf Root-Saving - Root-Saving Context zu persistenten Speicher speichert
NSManagedObjectContextDidSaveNotification
wird von Core Data gesendet. Der Standardkontext in der Hauptwarteschlange beobachtet dies und ruftmergeChangesFromContextDidSaveNotification:
mit derNSDictionary
von Änderungen am Hauptthread auf.- Es stürzt ab, wenn
objectID
an ein ungültiges Objekt gesendet wird (am wahrscheinlichsten wurde freigegeben).
Dies ist innerhalb der privaten Implementierung von NSManagedObjectContext
auftretenden mergeChangesFromContextDidSaveNotification:
so ist es für uns unmöglich, zu sehen, was eigentlich falsch hier gegangen ist; Alles, was wir an dieser Stelle sagen können, ist, dass ein Objekt, das existieren sollte, dies nicht tut.
Dies ist nur auf einem kleinen Prozentsatz von Core Data geschieht spart, was darauf hinweist, dass nicht ein grundlegender Fehler in unserem Core Data → API-Stack sein kann. Darüber hinaus gibt es keinen Hinweis darauf, dass die Größe oder der Typ der Änderungen (Einfügungen/Aktualisierungen/Löschungen) in den Kontextänderungen irgendeinen Einfluss auf die Wahrscheinlichkeit des Absturzes haben.
Welche Art von Nebenläufigkeit verwenden diese MOCs? Und verwenden Sie 'performBlock:' oder 'performBlockAndWait:' beim Zusammenführen von Änderungen? –
Das Standard-MoC verwendet den Hauptwarteschlangen-Parallelitätstyp und das Root-Speicher-MoC verwendet den Parallelitätstyp "Private Warteschlange". Jede Interaktion mit privaten Warteschlangen in der App verwendet performBlock oder performBlockAndWait. Wie in der Apple-Dokumentation beschrieben, interagieren wir nicht mit dem Default-Kontext durch die Ausführung von block, wir stellen jedoch sicher, dass wir niemals mit ihm interagieren, wenn wir nicht im Hauptthread sind. – JConway
Nur meine 2ct; Ich hatte einmal ein solches Problem, während ich alles nach dem Buch durchführte, und es wurde von einem 'NSLog()' des 'NSNotification'-Objekts (oder der 'userInfo'-Eigenschaft davon) verursacht. Seither mache ich nur 'mergeChangesFromContextDidSaveNotification:' unmittelbar gefolgt von 'save' im Kontext, ohne die Benachrichtigung auf andere Weise zu berühren. Seitdem habe ich es nie wieder segfault gesehen. – mvds