Questa è la mia prima domanda su Stack Overflow, quindi per favore scusami se interrompo qualsiasi etichetta. Sono anche abbastanza nuovo per la creazione di Objective-C/app.UIManagedDocument inserisce oggetti nel thread di sfondo
Ho seguito il corso di Stanford CS193P, in particolare, le conferenze/demo CoreData. Nell'app Photomania di Paul Hegarty, inizia con una vista tabella e inserisce i dati in background, senza alcuna interruzione nel flusso dell'interfaccia utente. Ho creato un'applicazione che elenca le attività commerciali nell'area locale (da un'API che restituisce i dati JSON).
Ho creato le categorie come da foto per fotografi/fotografi di Paul. La creazione delle classi stesse non è un problema, è dove vengono creati.
A simplified data structure:
- Section
- Sub-section
- business
- business
- business
- business
- business
- business
La mia applicazione si avvia con un UIViewController con diversi pulsanti, ognuno dei quali si apre un Tableview per la sezione corrispondente (questi tutti funzionano bene, sto cercando di fornire abbastanza informazioni in modo che la mia domanda ha un senso). Chiamo un metodo di supporto per creare/aprire l'URL per UIManagedDocument, che era basato su this question. Questo viene chiamato non appena l'applicazione viene eseguita e si carica rapidamente.
Ho un metodo molto simile a fetchFlickrDataIntoDocument di Paolo:
-(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] solo analizza i dati JSON e restituisce un NSArray contenente singoli businessses.
Ho eseguito il codice con un NSLog all'inizio e alla fine del codice di creazione dell'attività. Ogni azienda viene assegnata una sezione, impiega 0,006 secondi per creare e ce ne sono diverse centinaia. L'inserto ha una durata di circa 2 secondi.
Il Metodo Helper è qui:
// 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);
}];
}
}
e si chiama in viewDidLoad:
if (!self.lgtbDatabase) {
[ManagedDocumentHelper openDocument:@"DefaultLGTBDatabase" UsingBlock:^(UIManagedDocument *document){
[self useDocument:document];
}];
}
useDocument imposta solo self.document la documentazione fornita.
Desidero modificare questo codice in modo che i dati vengano inseriti in un altro thread e l'utente può ancora fare clic su un pulsante per visualizzare una sezione, senza importare i dati sospesi dall'interfaccia utente.
Qualsiasi aiuto sarebbe apprezzato Ho lavorato su questo problema per un paio di giorni e non sono stato in grado di risolverlo, anche con le altre domande simili qui. Se ci sono altre informazioni necessarie, fatemelo sapere!
Grazie
EDIT:
Finora questa domanda ha ricevuto uno verso il basso voto. Se c'è un modo per migliorare questa domanda, o qualcuno sa di una domanda che non sono stato in grado di trovare, potresti commentare come o dove? Se c'è un altro motivo per cui stai facendo downvoting, ti prego di farmelo sapere, poiché non sono in grado di capire la negatività e mi piacerebbe sapere come contribuire meglio.
Sei una leggenda assoluta! Ho usato la tua prima soluzione, perché a me sembrava più semplice capire. Purtroppo non posso darti l'upvote che meriti per questo, visto che mi sono appena iscritto, ma quando posso lo farò. Guarderò NSOperations in un secondo momento, dato che mi ha un po 'confuso. Ancora una volta, molte grazie per il tuo aiuto! –
Prego. Saluti. –
Solo per il completamento: non dimenticare di dire al tuo UIManagedDocument che si trova in uno stato sporco dopo l'operazione (e ogni altra). Quindi forzare un salvataggio chiamando '[document updateChangeCount: UIDocumentChangeDone]'. Questo è ciò che manca nel corso Stanford CS193P. –