In meiner App habe ich einen "Master" NSPrivateQueueConcurrencyType
Kontext, der als übergeordnetes Element zu einem NSMainQueueConcurrencyType
Kontext dient, auf den sich die View-Controller verlassen und weitergeben. Ich wollte dies tun, um Async-Speicher zu nutzen (diese App verwendet iCloud mit Core-Daten und spart viel Arbeit beim Exportieren von Ubiquity-Logs). Der Aufbau ist ähnlich den Zarra Ansatz am unteren Rande erwähnt von this articleLangsam löscht und speichert in verschachtelten NSManagedObjectContext
Speichert in der App sieht typischerweise wie:
[context save:nil];
[context.parentContext performBlock:^{
[context.parentContext save:nil];
}];
Dies scheint für kleine Änderungen/Updates gut zu funktionieren, aber ich bin verwirrt über was ich sehe, wenn ich viele Objekte lösche (z. B. ein Projekt löschen, das hunderte von Aufgabenobjekten enthält).
In dieser Situation ist das Speichern asynchron, aber es sieht so aus, als ob der Haupt-Thread in eine Semaphor-Wartesituation gerät (wie ich sehe, wenn ich den Debugger pausiere) und effektiv blockiert wird (ich kann nicht in der UI blättern) bis zum Hintergrund privater Kontext beendet das Speichern.
Tatsächlich habe ich gerade bemerkt, dass Swipe-to-Delete-Löschungen eines einzelnen Objekts trotz dieses Async-Speichermusters eine merkliche Verzögerung verursachen, so scheint es, dass alle Löschungen in der App langsam sind.
Wenn ich alternativ einen neuen NSPrivateQueueConcurrencyType
Kontext zuweisen, seinen persistenten Speicherkoordinator auf den Haupt-PSC im AppDelegate setzen und das Löschen und Speichern durchführen, macht es immer noch viel Arbeit, aber die Benutzeroberfläche wird nie blockiert (aber dann muss ich mir Sorgen machen, die Kontexte zu koordinieren, und zwar im Hauptkontext.
Irgendwelche Ideen, was ich falsch gemacht haben könnte, oder haben Sie dieses Verhalten auch gesehen?
Danke Jody!Ich stoße ständig auf deine hilfreichen Antworten. Ich mache noch etwas mehr Arbeit, um meine Probleme zu untersuchen. Auf einem Bildschirm präsentiere ich meine Projekte (Projekte haben viele Aufgaben) und verwenden keine NSFRC. Ich schaue mir die Dinge an, die du für meinen anderen Bildschirm erwähnt hast (der die Aufgaben auflistet und einen NSFRC verwendet), wo der Swipe-to-Delete eines einzelnen Tasks langsam ist und den verschachtelten Ansatz verwendet (und schnell, wenn ich zum Standard zurückkehre) NSMainQueueConcurrencyType-Kontext mit der PSC verbunden) – azsromej
Führen Sie es in Instrumenten. Das ist der beste Weg, um genau zu sehen, was passiert. –
Seltsamerweise führt das Verwenden von Swipe-to-Delete zu einem Speichervorgang, der die Benutzeroberfläche blockiert, aber mit der Schaltfläche Bearbeiten-Fertig, durch Antippen des roten Kreises und anschließend Löschen wird nicht blockiert, obwohl beide commitEditingStyle durchlaufen: forRowAtIndexPath (deleteObject: und speichern: passieren) – azsromej