Captación de fondo de Core Data a través de NSPrivateQueueConcurrencyType nuevo
core-data ios5 (2)
¿Es realmente tan simple ahora en iOS5?
Solía realizar una búsqueda de fondo usando este código en mi AppDelegate:
dispatch_queue_t downloadQueue = dispatch_queue_create("DownloadQueue", NULL);
dispatch_async(downloadQueue, ^{
self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:self.managedObjectContext];
[self.myDownloadClass download];
});
dispatch_release(downloadQueue);
Mi clase de descarga realiza una NSURLConnection para buscar algunos datos XML, utiliza NSXMLParser para analizar los datos y luego actualiza un esquema complejo en los datos principales. Siempre cambiaba al hilo principal para actualizar realmente los datos centrales. Código desordenado, con muchas llamadas a dispatch_sync (dispatch_get_main_queue () ....
Mi nuevo código se ve así:
NSManagedObjectContext *child = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[child setParentContext:self.managedObjectContext];
[child performBlock:^{
self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:child];
[self.myDownloadClass download];
}];
junto con un pequeño cambio a algún otro código en mi AppDelegate para establecer el tipo de contexto del objeto del modelo padre en NSMainQueueConcurrencyType:
- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext != nil)
{
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
{
__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return __managedObjectContext;
}
Parece que funciona muy bien. Todo el proceso de actualización aún se ejecuta en un hilo separado, pero no tuve que crear un hilo. Parece magia.
Solo recuerde que si desea enviar los cambios a los archivos de datos básicos físicos, también tiene la función de guardar llamada en el contexto principal.
Realmente no hice una pregunta aquí. Estoy publicando esto, así que ayuda a los demás porque todo lo que encontré cuando buscaba los nuevos métodos de contexto de objetos administrados iOS5 solo proporcionaba detalles de alto nivel sin ejemplos de código Y todas las otras búsquedas para buscar datos básicos en el fondo son antiguas, a veces muy antiguas y analiza cómo hacerlo antes de iOS5.
Estoy tratando de entender cómo se implementa esta nueva API. Mi patrón habitual para los datos básicos multiproceso es algo como esto:
Usualmente en un NSOperation
pero simplificado usando dispatch_async
en este ejemplo:
dispatch_queue_t coredata_queue; // some static queue
dispatch_async(coredata_queue, ^() {
// get a new context for this thread, based on common persistent coordinator
NSManagedObjectContext *context = [[MyModelSingleton model] threadedContext];
// do something expensive
NSError *error = nil;
BOOL success = [context save:&error];
if (!success) {
// the usual.
}
// callback on mainthread using dispatch_get_main_queue();
});
A continuación, el hilo principal responderá actualizando la interfaz de usuario basada en NSManagedObjectContextDidSaveNotification
para fusionar el contexto principal.
Las nuevas API parecen ser un envoltorio alrededor de este patrón, donde parece que el contexto child
simplemente toma al coordinador persistente de su padre para crear un nuevo contexto. Y al especificar NSPrivateQueueConcurrencyType
en init, se asegurará de que el parámetro performBlock
se ejecute en la cola privada.
La nueva API no parece ser mucho menos código para escribir. ¿Alguna ventaja sobre el enhebrado ''tradicional''?
Sí, es realmente así de fácil ahora (en iOS 5.0). Para compatibilidad con iOS 4, los obstáculos previos permanecen, pero la documentación no es demasiado mala para el confinamiento del hilo. ¿Tal vez deberías agregar esto a una sección wiki?