8

el problema que estoy encontrando es la siguiente:datos básicos: Antecedentes traiga, NSFetchedResultsController y Ordenación tiempo

Tengo un UITableView, que me alimento con los datos de un NSFetchedResultsController que recupera alrededor de 6000 filas de datos básicos. El fetchBatchSize del NSFetchRequest se establece en 20 y si no aplica ningún NSSortDescriptor, la recuperación es lo suficientemente rápida como para no bloquear el subproceso de la interfaz de usuario.

Sin embargo, yo necesito para mostrar los registros ordenados alfabéticamente para que uso el NSSortDescriptor siguiente:

[[[NSSortDescriptor alloc] initWithKey:@"optionText" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] autorelease]; 

Y aquí es cuando las cosas cambian, la operación de búsqueda ahora toma alrededor de 3 segundos para completar porque el 6000 las filas están siendo ordenadas Obviamente, durante esos segundos, la IU está bloqueada y la experiencia del usuario es terrible.

Sé que podría hacer la búsqueda en un hilo de fondo y luego pasar a los ID de objeto al hilo principal, pero en ese caso, ¿cómo podría seguir usando el NSFetchedResultsController en el hilo principal (también lo estoy usando para observar cambios en los datos)?

También tengo indexed atributo en el que estoy ordenando pero que solo optimiza las búsquedas y no clasifica el rendimiento.

¡Cualquier idea sería muy apreciada, gracias!

+0

pregunta estúpida pero supongo que no puede ordenar previamente los datos antes de cargarlos en Core Data? –

+0

Pregunta estúpida, en el momento en que ejecuta la solicitud de recuperación ¿cuál es el valor de managedObjectContext.hasChanges? – Drew

Respuesta

0

primer todos, NSFetchedResultsController se usa normalmente en el hilo principal. Y no es compatible con la recuperación de fondo hasta ahora, lanzamiento de Apple iOS 6.

Por lo tanto, cuando invoca el performFectch de NSFetchedResultController, debe "bloquear" el hilo principal por un tiempo. Sin embargo, queremos que el tiempo sea mínimo.

(Por lo que podía recordar, debe establecer un descriptor de tipo de NSFetchedResultController. Así que no estoy seguro de cómo lo hiciste funciona mientras no se establece un descriptor de tipo. Echar un vistazo a la referencia de clase)

No estoy seguro de si está utilizando la Tienda Sqlite. Si es así, no puedo creer que funcione tu clase de descriptor. (eche un vistazo a la Guía de programación de datos básicos: sección de solución de problemas). Si no, mantener tantos datos en la memoria no sería una buena idea

Finalmente llegamos al punto por el cual es lento. Este tipo que usa "localizedCaseInsensitiveCompare:" hace que su búsqueda sea lenta ya que la secuencia de comparación Unicode sería lenta. (mencionado en WWDC 2010 Core Data Performance en iPhone).

Como muchas otras aplicaciones, debe crear un campo/propiedad de cadena no Unicode en función de su "optionText" y ordenar en función de esa propiedad de cadena no Unicode.

+1

¿alguien podría explicar el voto negativo? –

-4

Ha intentado ejecutar el performFetch: método en el fondo, ya sea con

[controller performSelectorInBackground:@selector(performFetch) withObject:nil]; 

o

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 
    [controller performFetch]; 
}); 
+1

Esta no es una solución segura. NSFetchedResultsController tiene managedObjectContext que no es seguro para subprocesos. –

+0

Estoy de acuerdo con @Tal Bereznitskey. ¿Alguna otra idea? – monchote

0

El uso de un caché, probablemente ayudará a obtener un mejor rendimiento.

Tengo el mismo problema y me di cuenta de que en la primera llamada la búsqueda necesita más de 3 segundos, pero al realizar la búsqueda dos veces, se muestran inmediatamente sus resultados.

+0

Sí, la memoria caché ayuda para las recuperaciones posteriores, pero la primera sigue siendo terriblemente lenta, bloqueando notablemente el subproceso de la interfaz de usuario. – monchote

0

Mostrar 6000 filas en una tabla puede no ser la mejor solución en términos de experiencia del usuario. Tal vez deberías agregar una tabla de filtro antes. Similar a los grupos en la libreta de direcciones. Esto podría mejorar la experiencia del usuario si logra reducir el número de filas por opción de filtro a un número más manejable. Esto reduciría el tiempo de carga y el tiempo de desplazamiento.

No sé qué tipo de datos está mostrando, por lo que tal vez no hay más remedio que mostrar todo en una larga lista. Para las personas, podrías agregar opciones para sexo y grupos de edad. Para automóviles, puede agregar un filtro por marca y modelos ...

+0

Sé que no es el mejor diseño de interfaz de usuario, pero es un requisito y el cliente no está dispuesto a cambiarlo. Realmente creo que NSFetchedResultsController debería admitir recuperaciones de fondo. Gracias por tu comentario. – monchote

3

¿Qué le parece usar la propiedad batchSize de NSFetchRequest?

Si establece un tamaño de lote distinto de cero, la colección de objetos devueltos cuando se ejecuta la extracción se divide en lotes. Cuando se ejecuta la recuperación , se evalúa toda la solicitud y se registran las identidades de todos los objetos coincidentes , pero no se extraen datos de los objetos batchSize del almacén persistente a la vez. La matriz devuelta al ejecutar la solicitud será un objeto proxy que falla de forma transparente los lotes bajo demanda.(En términos de base de datos, esto es una cursor en memoria.)

1

hago un importaciones fondo por lotes en un NSOperation que utiliza un NSManagedObjectContext separada. Periódicamente guardo el segundo contexto, que dispara una notificación para actualizar mi NSManagedContext principal en el que está conectado mi NSFetchedResultsController.

Tal vez una técnica similar podría aplicarse a de Explorar

Aquí es un cacao es mi novia artículo sobre el tema:

http://www.cimgf.com/2011/05/04/core-data-and-threads-without-the-headache/

y la técnica también se menciona en la guía de programación de datos básicos 'importar' en lotes

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html#//apple_ref/doc/uid/TP40003174-SW1

Cuestiones relacionadas