Ho un'app basata su UIDocument
che utilizza NSFileWrapper
s per archiviare i dati. Il wrapper di file "master" contiene molti wrapper di file di directory aggiuntivi, ognuno dei quali rappresenta una pagina diversa del documento.UIDocument & NSFileWrapper - file di grandi dimensioni che richiedono molto tempo per il salvataggio, nonostante le modifiche incrementali
Quando si salva un documento di grandi dimensioni per la quale è stata modificata solo una piccola parte di una pagina, UIDocument
trascorre un tempo lungo nel scrivere le modifiche (in writeContents:andAttributes:safelyToURL:forSaveOperation:error:
) di sfondo. Sicuramente dovrebbe scrivere solo questa piccola modifica al file wrapper ... cosa ci vuole così tanto tempo?
mio contentsForType:error:
di override restituisce un nuovo involucro file di directory con il contenuto del file master involucro (à 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]];
}
Ed ecco una bella foto di una traccia dello stack da Time Profiler:
per inciso, si dice ~ 1.6s in questo thread di lavoro per risparmiare - in fase di esecuzione effettivo questo equiparato a circa 8 secondi.
Edit:
C'è qualche modo per verificare se i wrapper di file richiedono la scrittura su disco o no? Solo così posso confermare che non sto facendo qualcosa di strano come aggiornare ogni sottocartella quando apporto una piccola modifica (anche se sono sicuro di non esserlo ...).
Edit:
ho avuto un ulteriore giocare con l'applicazione CloudNotes del campione, e sembra che NSFileWrapper
fa attuare il risparmio incrementale, almeno in questo caso! L'ho provato inizializzando un documento con 100 note, ognuna delle quali conteneva circa 5 MB di dati. Ho fatto una piccola modifica qua e là (un singolo carattere che cambia in una vista testuale indica che il documento ha bisogno di essere salvato), e ho registrato all'incirca quanto tempo ogni salvataggio ha richiesto. Il test è relativamente grezza (ed eseguire sul simulatore), ma i risultati sono stati qualcosa di simile:
- prima di scrittura: ~ 8000ms
- 2 ° scrittura: ~ 4000ms
- 3 ° scrittura: ~ 300ms
- scrive tutti successive: ~ 40ms
Ovviamente ci sono molti fattori che influenzano il tempo necessario, in particolare dal momento che è il risparmio utilizzando coordinamento file in un thread in background, ma in generale la tendenza sembra sempre di essere questo tipo di exponen decadimento, fino a quando tutte le scritture diventano veramente molto veloci.
Ma sto ancora cercando di capire perché questo non accade nella mia app. Per un documento di più pagine di grandi dimensioni (grande, ma ancora molte volte più piccolo del documento per il test di CloudNotes che ho eseguito sopra), l'utente può attendere molti secondi prima che un documento venga chiuso. Non voglio dover mettere un filatore per qualcosa che dovrebbe essere praticamente istantaneo.
Stai eseguendo un salvataggio automatico o stai salvando tutto in una volta? Stai iniziando il salvataggio dal thread principale? Sostituisci ogni NSFileWrapper o solo quelli che sono effettivamente cambiati? – Luke
Mi affido esclusivamente al salvataggio automatico, quindi i salvataggi sono avviati da UIDocument, facendo la solita cosa di chiamare 'contentsForType: error:' (thread principale) prima di scrivere (thread in background). Sto solo sostituendo i wrapper di file che ho modificato (_quando_ cambiano). Tuttavia, ho notato che sto usando un metodo che guarda tutti i miei wrapper di file di pagina e li ordina in una matrice ordinata. Penso che questo stia scherzando con il pigro caricamento di NSFileWrapper e causando la necessità di scrivere in qualche modo. Sto solo implementando un indice in modo da non doverlo fare e vedrò che differenza fa. – Stuart
No, cambiare solo usando un file indice per tenere traccia delle pagine/numeri di pagina non ha aiutato. Sto ancora cercando di rintracciare cosa potrebbe causare il lento risparmio. – Stuart