Ich habe eine UIDocument
basierte Anwendung, die NSFileWrapper
s verwendet, um Daten zu speichern. Der "Master" -Datei-Wrapper enthält viele zusätzliche Verzeichnisdatei-Wrapper, von denen jeder eine andere Seite des Dokuments darstellt.UIDocument & NSFileWrapper - große Dateien eine lange Zeit zu sparen, trotz inkrementellen Änderungen
Wenn ein großes Dokument, für das Speichern nur ein kleiner Teil einer Seite geändert wurde, verbringt UIDocument
eine lange Zeit im Hintergrund die Änderungen (in writeContents:andAttributes:safelyToURL:forSaveOperation:error:
) zu schreiben. Sicherlich sollte es nur eine kleine Änderung am Datei-Wrapper schreiben ... was dauert so lange?
Meine contentsForType:error:
Überschreibung gibt einen neue Verzeichnisdatei Wrapper mit dem Inhalt des Master-Datei-Wrapper (à la WWDC 2012 Session 218 - Using iCloud with UIDocument):
- (id)contentsForType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
if (!_fileWrapper) {
[self setupEmptyDocument];
}
return [[NSFileWrapper alloc] initDirectoryWithFileWrappers:[_fileWrapper fileWrappers]];
}
Und hier ist ein schönes Bild von einem Stack-Trace von Time Profiler:
übrigens sagt es ~ 1,6s in diesem Arbeitsthread zu speichern - in der tatsächlichen Laufzeit dies etwa 8 Sekunden gleichgesetzt.
Edit:
Gibt es irgendeine Art und Weise kann ich überprüfen, ob die Datei-Wrapper auf die Festplatte zu schreiben erfordert oder nicht? Nur so kann ich bestätigen, dass ich nicht irgendwie etwas Seltsames mache, wie jeden Unterdatei-Wrapper zu aktualisieren, wenn ich eine kleine Änderung mache (obwohl ich mir sicher bin, dass ich nicht ... bin).
Edit:
Ich hatte einen weiteren mit der CloudNotes Beispielanwendung rumspielen, und es scheint, dass NSFileWrapper
nicht inkrementelle Einsparung realisieren, zumindest in diesem Fall! Ich habe es getestet, indem ich ein Dokument mit 100 Notizen initialisiert habe, von denen jedes etwa 5 MB Daten enthielt. Ich habe hier und da eine kleine Änderung vorgenommen (eine einzelne Zeichenänderung in einer Textansicht markiert das Dokument als zu speichernd) und ungefähr aufgezeichnet, wie lange jede Speicherung dauerte. Der Test ist relativ grobes (und auf dem Simulator laufen), aber die Ergebnisse waren so etwas wie diese:
- 1. schreiben: ~ 8000ms
- 2. schreiben: ~ 4000ms
- 3. schreiben: ~ 300ms
- alle nachfolgenden schreibt: ~ 40ms
Offensichtlich gibt es viele Faktoren, die die Zeit, die beeinflussen, zumal es in einem Hintergrundthread Datei Koordination mit rettende, aber im allgemeinen die Tendenz scheint immer diese Art von exponen zu sein Verfall, bis alle Schreibvorgänge wirklich sehr schnell werden.
Aber ich versuche immer noch herauszufinden, warum das in meiner App nicht passiert. Bei einem großen mehrseitigen Dokument (groß, aber immer noch um ein Vielfaches kleiner als das oben für den CloudNotes-Test ausgeführte Dokument) kann der Benutzer viele Sekunden auf das Schließen eines Dokuments warten. Ich möchte keinen Spinner für etwas aufbieten müssen, das praktisch sofort sein sollte.
Machst du eine automatische Speicherung oder speichst du alles auf einmal? Initiieren Sie das Speichern aus dem Hauptthread? Ersetzen Sie jeden NSFileWrapper oder nur die, die sich tatsächlich geändert haben? – Luke
Ich verlasse mich ausschließlich auf das automatische Speichern, also werden die Sicherungen von UIDocument initiiert, indem man 'contentsForType: error:' (main thread) aufruft, bevor man schreibt (background thread). Ich ersetze nur die Datei-Wrapper, die ich geändert habe (_wenn sie sich ändern). Ich habe jedoch bemerkt, dass ich eine Methode verwende, die alle meine Seiten-Datei-Wrapper betrachtet und sie in ein geordnetes Array sortiert. Ich denke, dass dies mit dem faulen Laden von NSFileWrapper zusammenhängt und dazu führt, dass sie irgendwie schreiben müssen. Ich implementiere gerade einen Index, so dass ich das nicht machen muss und sehe, welchen Unterschied es macht. – Stuart
Nein, es hat nicht geholfen, nur eine Indexdatei zu verwenden, um die Seiten/Seitenzahlen zu verfolgen. Ich versuche immer noch herauszufinden, was das langsame Speichern verursachen könnte. – Stuart