Rendimiento de eliminar carpetas con muchos files en iOS

Supongamos que tengo una carpeta en el directory de datos de mi aplicación iOS con varios miles de pequeños files. Al eliminar esta carpeta (a través de [NSFileManager removeItemAtPath] ) se toma una cantidad de time no trivial. Pero en OS X, eliminar una carpeta con los mismos contenidos es muy rápido. Parece simplemente desvincular la carpeta del sistema de files. Entonces, ¿por qué tarda tanto iOS? ¿Cuál es la diferencia?

Editar: en un iPad 3, eliminar 3 carpetas con 5,000 a 9,000 files tarda aproximadamente 35 segundos. En el simulador que se ejecuta en un Retina MBP anterior, tarda aproximadamente 1,5 segundos.

La estructura jerárquica que ve no es "real": los directorys no son contenedores físicos para los files que parecen contener. La jerarquía del directory es una ficción cuidadosamente mantenida.

Irrelevante a un lado: el sistema de files original de Mac llevó esto un paso más allá, hizo que la estructura de directorys fuera totalmente una ficción visual, todos los files estaban en la raíz del disco (3,5 ") y solo parecía estar dispuesto en carpetas. Afortunadamente esto fue suplantado por HFS.

Es mejor pensar en directorys / carpetas como un tipo especial de file que contiene un índice para un set de files que pretende contener.

Conceptualmente, esto funciona de forma muy parecida a la gestión clásica de la memory del cocoa. Cada (directory / object) "posee" un set de (files / objects) por reference ("conserva" el (file / object)).

Cuando elimina un file de un directory, se "libera". Si ningún otro directory tiene un reclamo de propiedad en ese file, es "desocupado".

Su (carpeta / object) no contiene los objects que "posee". Realmente ni siquiera los "posee", solo tiene un "reclamo de propiedad" sobre ellos.

Del artículo de Wikipedia sobre enlaces duros:

"un enlace duro es una input de directory que asocia un nombre con un file en un sistema de files. Un directory es en sí mismo un tipo especial de file que contiene una list de tales inputs".

Tenga en count que debido al uso de enlaces duros es posible tener un solo file físico que pueda aparecer en múltiples directorys. Cada uno de esos directorys posee una reference al file "real". Cada reference es tan "real" como cualquier otra. Todas las references deben estar "desvinculadas" para que el file se marque como eliminado.

¡El "file" puede incluso tener diferentes "nombres" en los diferentes directorys!

Los enlaces duros son la sierra de cadena de las características del sistema de files: potente, pero potencialmente bastante peligroso. Tenga en count que la interfaz gráfica de usuario de OSX no ofrece medios para producir enlaces duros, ni siquiera enlaces simbólicos.

Desde este elemento de la list de correo electrónico .

Ahora sobre iOS

[NSFileManager removeItemAtPath: error:], lo que hace bajo el capó es que iterar a través de los subdirectorys y files y eliminarlos primero. Esto lleva time. Me interesa si es posible hacer esto al instante, sin siquiera una recursión implícita. ¿Quita el directory y desaparecerían los files y subdirectorys?

lo que puedes hacer es

  1. Si le preocupa el time que esto tomaría y necesita un resultado instantáneo, puede cambiar el nombre de la carpeta (que es prácticamente instantánea) y luego eliminar la carpeta renombrada y su contenido en un hilo de background.

  2. Si el time es una restricción, intente ejecutar el process de eliminación en un subprocess de background, si no es un problema.

¿Estás haciendo tus testings en el dispositivo y una Mac, o simulador y Mac.
En el primer caso, la diferencia se debe al hardware, un iphone es más lento que un mac.
En el segundo caso, debería pensar que es un simulador, por lo que el mecanismo interno podría ser diferente de alguna manera.
¿Cuál es la diferencia en segundo lugar sobre los dos processs?

No realice tareas largas en el hilo principal. Considera que quieres eliminar todo el contenido del directory de documentos.

 - (void) deleteDocumentsDirectoryContents { NSString *folderPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSError *error = nil; for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:folderPath error:&error]) { [[NSFileManager defaultManager] removeItemAtPath:[folderPath stringByAppendingPathComponent:file] error:&error]; } } 

Llama a la function anterior de esta manera.

 [self performSelectorInBackground:@selector(deleteDocumentsDirectoryContents) withObject:nil]; 
    Intereting Posts