Das ist meine erste Frage zu Stack Overflow, also bitte entschuldigt mich, wenn ich irgendeine Etikette breche. Ich bin auch ziemlich neu in der Objective-C/App-Erstellung.UIManagedDocument fügt Objekte in den Hintergrund ein Thread
Ich habe den CS193P Stanford Kurs, insbesondere die CoreData Vorlesungen/Demos, verfolgt. In der Photomania-App von Paul Hegarty beginnt er mit einer Tabellenansicht und füllt die Daten im Hintergrund auf, ohne den UI-Fluss zu unterbrechen. Ich habe eine Anwendung erstellt, die Unternehmen im lokalen Bereich auflistet (aus einer API, die JSON-Daten zurückgibt).
Ich habe die Kategorien nach Pauls Foto-/Fotografenklassen erstellt. Die Erstellung der Klassen selbst ist kein Problem, dort werden sie erstellt.
A simplified data structure:
- Section
- Sub-section
- business
- business
- business
- business
- business
- business
Meine Anwendung beginnt mit einem UIViewController mit mehreren Tasten, von denen jede eine Tableview für den entsprechenden Abschnitt öffnet (diese alle gut funktionieren, ich versuche, genügend Informationen zur Verfügung zu stellen, so dass meine Frage Sinn macht). Ich rufe eine Hilfsmethode zum Erstellen/Öffnen der URL für das UIManagedDocument auf, das auf this question basiert. Dies wird aufgerufen, sobald die Anwendung ausgeführt wird, und es wird schnell geladen.
Ich habe eine Methode sehr ähnlich wie Paul fetchFlickrDataIntoDocument:
-(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] analysieren nur die JSON-Daten und gibt eine NSArray einzelne businessses enthält.
Ich habe den Code mit einem NSLog am Anfang und Ende des Business-Erstellung-Code ausgeführt. Jedem Unternehmen ist ein Abschnitt zugewiesen, für dessen Erstellung 0,006 Sekunden benötigt werden, und es gibt mehrere hundert davon. Der Einsatz endet etwa 2 Sekunden.
Die Helper-Methode ist hier:
// 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);
}];
}
}
Und in viewDidLoad genannt wird:
if (!self.lgtbDatabase) {
[ManagedDocumentHelper openDocument:@"DefaultLGTBDatabase" UsingBlock:^(UIManagedDocument *document){
[self useDocument:document];
}];
}
useDocument nur setzt self.document der bereitgestellten Dokument.
Ich möchte diesen Code ändern, so dass die Daten in einen anderen Thread eingefügt werden, und der Benutzer kann immer noch auf eine Schaltfläche klicken, um einen Abschnitt anzuzeigen, ohne den Datenimport hängen die Benutzeroberfläche.
Jede Hilfe wäre willkommen Ich habe an diesem Thema für ein paar Tage gearbeitet und konnte es nicht lösen, auch nicht mit den anderen ähnlichen Fragen hier. Wenn Sie weitere Informationen benötigen, lassen Sie es mich bitte wissen!
Danke
EDIT:
Bisher in dieser Frage eine nach unten Abstimmung erhalten hat. Wenn es einen Weg gibt, diese Frage zu verbessern, oder jemand eine Frage kennt, die ich nicht finden konnte, könntest du bitte kommentieren, wie oder wo? Wenn es einen anderen Grund für die Ablehnung gibt, lassen Sie es mich wissen, da ich die Negativität nicht verstehen kann und gerne lernen würde, besser beizutragen.
Sie sind eine absolute Legende! Ich habe deine erste Lösung benutzt, denn mir schien es einfacher zu verstehen. Leider kann ich dir die Aufwertung nicht geben, die du so verdient hast, da ich gerade erst beigetreten bin, aber wenn ich kann, werde ich es tun. Ich werde zu einem späteren Zeitpunkt in NSOperations schauen, da das mich ein wenig verwirrt. Nochmals vielen Dank für Ihre Hilfe! –
Gern geschehen. Prost. –
Nur für den Abschluss: Vergessen Sie nicht, Ihrem UIManagedDocument mitzuteilen, dass es sich nach Ihrer (und jeder anderen) Operation in einem schmutzigen Zustand befindet. Erzwinge also ein Speichern durch Aufruf von '[document updateChangeCount: UIDocumentChangeDone]'. Dies ist, was im CS193P Stanford Kurs fehlt. –