Esta es mi primera pregunta sobre el desbordamiento de pila, así que discúlpeme si estoy rompiendo alguna etiqueta. También soy bastante nuevo en la creación de Objective-C/app.UIManagedDocument insertar objetos en el hilo de fondo
He seguido el curso CS193P de Stanford, en particular, las clases/demostraciones de CoreData. En la aplicación Photomania de Paul Hegarty, comienza con una vista de tabla y rellena los datos en segundo plano, sin interrupción del flujo de la interfaz de usuario. He estado creando una aplicación que enumera negocios en el área local (desde una API que devuelve datos JSON).
He creado las categorías según las clases de fotógrafo/fotógrafo de Paul. La creación de las clases en sí mismas no es un problema, es el lugar donde se están creando.
A simplified data structure:
- Section
- Sub-section
- business
- business
- business
- business
- business
- business
Mi aplicación se inicia con un UIViewController con varios botones, cada uno de los cuales abre una tableview para la sección correspondiente (todos éstos funcionan bien, estoy tratando de proporcionar suficiente información para que mi pregunta tiene sentido). Llamo a un método de ayuda para crear/abrir la URL para el UIManagedDocument, que se basó en this question. Esto se invoca tan pronto como se ejecuta la aplicación y se carga rápidamente.
que tienen un método muy similar a fetchFlickrDataIntoDocument de Pablo:
-(void)refreshBusinessesInDocument:(UIManagedDocument *)document
{
dispatch_queue_t refreshBusinessQ = dispatch_queue_create("Refresh Business Listing", NULL);
dispatch_async(refreshBusinessQ, ^{
// Get latest business listing
myFunctions *myFunctions = [[myFunctions alloc] init];
NSArray *businesses = [myFunctions arrayOfBusinesses];
// Run IN document's thread
[document.managedObjectContext performBlock:^{
// Loop through new businesses and insert
for (NSDictionary *businessData in businesses) {
[Business businessWithJSONInfo:businessData inManageObjectContext:document.managedObjectContext];
}
// Explicitly save the document.
[document saveToURL:document.fileURL
forSaveOperation:UIDocumentSaveForOverwriting
completionHandler:^(BOOL success){
if (!success) {
NSLog(@"Document save failed");
}
}];
NSLog(@"Inserted Businesses");
}];
});
dispatch_release(refreshBusinessQ);
}
[MyFunctions arrayOfBusinesses] simplemente analiza los datos JSON y devuelve un NSArray contiene businessses individuales.
He ejecutado el código con un NSLog al principio y al final del código de creación de negocio. A cada negocio se le asigna una sección, toma 0.006 segundos para crear, y hay varios cientos de estos. El inserto termina tomando alrededor de 2 segundos.
El método de ayuda está aquí:
// The following typedef has been defined in the .h file
// typedef void (^completion_block_t)(UIManagedDocument *document);
@implementation ManagedDocumentHelper
+(void)openDocument:(NSString *)documentName UsingBlock:(completion_block_t)completionBlock
{
// Get URL for document -> "<Documents directory>/<documentName>"
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:documentName];
// Attempt retrieval of existing document
UIManagedDocument *doc = [managedDocumentDictionary objectForKey:documentName];
// If no UIManagedDocument, create
if (!doc)
{
// Create with document at URL
doc = [[UIManagedDocument alloc] initWithFileURL:url];
// Save in managedDocumentDictionary
[managedDocumentDictionary setObject:doc forKey:documentName];
}
// If the document exists on disk
if ([[NSFileManager defaultManager] fileExistsAtPath:[url path]])
{
[doc openWithCompletionHandler:^(BOOL success)
{
// Run completion block
completionBlock(doc);
} ];
}
else
{
// Save temporary document to documents directory
[doc saveToURL:url
forSaveOperation:UIDocumentSaveForCreating
completionHandler:^(BOOL success)
{
// Run compeltion block
completionBlock(doc);
}];
}
}
y se llama en viewDidLoad:
if (!self.lgtbDatabase) {
[ManagedDocumentHelper openDocument:@"DefaultLGTBDatabase" UsingBlock:^(UIManagedDocument *document){
[self useDocument:document];
}];
}
useDocument simplemente establece self.document al documento proporcionado.
Me gustaría modificar este código para que los datos se inserten en otro hilo, y el usuario todavía puede hacer clic en un botón para ver una sección, sin que la importación de datos cuelgue la interfaz de usuario.
Me agradecería cualquier ayuda He trabajado en este tema durante un par de días y no he podido resolverlo, incluso con las otras preguntas similares aquí. Si hay otra información que necesita, ¡por favor hágamelo saber!
Gracias
EDIT:
Hasta ahora esta pregunta ha recibido uno abajo voto. Si hay alguna manera de mejorar esta pregunta, o alguien sabe de una pregunta que no he podido encontrar, ¿podría comentar cómo o dónde? Si hay otra razón por la que está bajando la votación, hágamelo saber, ya que no puedo entender la negatividad, y me encantaría aprender a contribuir mejor.
¡Eres una leyenda absoluta! He usado tu primera solución, ya que a mí me pareció más fácil de entender. Lamentablemente, no puedo darte el voto que mereces por esto, ya que acabo de unirme, pero cuando pueda lo haré. Examinaré NSOperations en una fecha posterior, ya que eso me confundió un poco. Una vez más, muchas gracias por tu ayuda! –
De nada. Aclamaciones. –
Solo para completar: no se olvide de informar a su UIManagedDocument que está en estado sucio después de su (y cualquier otra) operación. Así que fuerce un guardado llamando '[document updateChangeCount: UIDocumentChangeDone]'. Esto es lo que falta en el curso CS193P de Stanford. –