CoreData multi threading

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • CoreData multi threading

    Moin,

    Folgendes Problem. Ich habe eine sehr große und komplexe Anwendung in der CoreData auf verschiedenen Threads ausgeführt wird. Das Problem dabei ist, dass ich in unregelmäßigen Abständen Crashes beim löschen einiger Objekte bekomme. Die App stürzt ab mit "CoreData could not fulfill a fault for ..." wie kann ich dieses Problem umgehen ? Bin für jeden Tipp dankbar.

    gruß
  • Core Data ist nicht threadsafe.
    Jede Core Data Operation in unterschiedlichen Threads ist 'gefährlich', keine ist 'sicher'.
    ManagedObject ist nicht threadsafe.
    AppKit und UIKit sind in einigen Belangen nicht threadsafe.
    Bindings und Controller sind nicht threadsafe.

    Insofern ist Core Data in Verbindung mit Threading vielleicht nicht die allerbeste Idee.

    Falls es aber dennoch notwendig sein sollte, gab es seinerzeit einen Concurrency Guide.
    Dieser ist angeblich 'outdated'.

    Wenn Du also irgendwie mit Core Data und Threads arbeitest, solltest Du dennoch diesen veralteten Guide umsetzen.
    Wenn Du hingegen bereits diesen Guide umsetzt, solltest Du Dich mit einem Experten von Apple auseinandersetzen.
    (Und wenn das alles ganz viel Zeit hat kannst Du auf eine überarbeitete Version des Guides warten.)
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Normalerweise schreibt man ja nicht mit vielen Threads. Man liest mehr. Lesen ist unkritisch wenn du diese ChangeNotification beachtest. Das steht in dem Concurrency Guide drin den Marco verlinkt hat

    Du kannst als Workaround einfach das Schreiben in CoreData Kapseln und mit performSelectorOnMainThread mit WaitUntilDone=YES ausführen. Dadurch wird es natürlich langsamer. Wenn du also wirklich von vielen Threads aus schreibend auf CoreData zugreifen willst, wird das nicht viel bringen.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Also es gibt ja einen neuen Concurrency-Guide und in der Tat sollte man nur diesem folgen. Nur.

    Aber CD und Nebenläufigkeit ist keine nette Sache. Nicht unmöglich, aber nicht nett. Ich habe das aktuell bei einem eigenen ORM, welches ich für Objective-Cloud schreibe. Und da setzt man sich ja mit CD aus und den Problemen von CD und deren Ursachen.

    Ich habe den großen Nachteil, dass das bei mir "automatisch" Parallel funktionieren muss. Da kommen einfach zwei Requests herein. Die kennen sich im Zweifel nicht einmal. Eigene Handgriffe des App-Entwicklers kann ich da nicht erwarten. Aber ist das so ein großer Nachteil? Funktioniert so etwas nicht auf vielen Servern mit vielen Programmiersprachen bei vielen Frameworks und vielen rDBMS einfach klaglos? Ja, tut es. Wieso? Und wieso bei CD nicht? Weil bei rDBMS das ein seit jeher bestehender Klassiker ist und von sehr vielen sehr schlauen Leuten durchdacht wurde. Da gibt es mehr Diplom- und Doktorarbeiten als Sandkörner am Mehr.

    Und was macht CD? Es nutzt das alles nicht. Epic-Fail? Nein, so war CD einfach nicht gedacht. Da wird ein Dokument(!) geöffnet, besessen, verändert, gespeichert und geschlossen. Das ist einfach ein Grundkonzept, welches sich maßgeblich gegen Concurrency wehrt. Der Hintergrund ist einfach, dass es so schön OOP und wenig rDBMS ist – mit allen Vor- und Nachteilen. Aber damals(TM) war das auch noch nicht so wichtig. Wenn man dann heute auch noch transparente Asynchronität hereinbekommt (iCloud), wird es für den App-Programmierer eklig.

    Nein, ich rte nicht grundlegend von CD + Nebenläufigkeit ab. Ich empfehle aber dringend, das alles stets zu bedenken. Das Problem zeigt sich übrigens ganz einfach:

    1
    Mache einen Fetch, der 10 Objekte trifft. Diese werden als Fault geladen.

    2
    Lösche eines der 10 Objekte und speichere das ganze bis hoch zum Store.

    3
    Greife in einer dummen Schleife auf die 10 Objekte zu. Fault wird gefeuert. Und eine Exception.

    Das geht übrigens auch ganz ohne Nebenläufigkeit. Nur ist man dann nicht so sagenhaft dämlich, sich ins Knie zu schießen. In einer nebenläufigen Operation wird das Ganze aber lustig. Und nein, mit ein paar eingebauten Queues und Contexthierarchien löst sich das Problem nicht wie von selbst. Es löst sich nur durch aufpassen.

    Was würde eine rDBMS machen? Es würde bei 2 das Problem erkennen und entweder serialisieren oder eine Transaction verweigern. Man kann die dann ja neu durchführen (mit etwa nur 9 Objekten). Das hat den Nachteil, dass ich möglicherweise in meiner App den State außerhalb der rDB restaurieren muss. Interessiert das rDBMS nicht. Das ist dann der Nachteil.

    Ach, so, neuerdings soll man ja ständig sichern, am besten nach jeder Operation. Apple, so macht man aus Dokumenten noch lange keine Transactions, auch wenn es das wohl mal werden soll oder sollte.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?