Ausführung von Core Data speichern auf einem hintergrund-thread?
Habe ich eine Schaltfläche, die markiert einen ausgewählten Eintrag in einem Core Data, SQLite als "Favorit", das heißt, ich bin nur umlegen eines BOOL
für diesen index von off auf on stellen.
Derzeit, wenn ich dieses, ich nenne save
auf die managedObjectContext
nimmt, die vielleicht 500ms, vielleicht ein wenig mehr, nach Instrumenten.
Ich habe einige code, der ausgeführt wird, zur gleichen Zeit, die Trigger eine nette kleine Teilchen-explosion ("Hurra, ein Favorit!"), aber ich laufen in ein Problem, wo die explosion verzögert wird, bis nach der save
abgeschlossen hat.
Ich bin mir nicht sicher, warum, da der code zum auslösen der explosion ist vor der save
nennen. Ich bin ein relativ neuer Programmierer also vielleicht bin ich etwas fehlt, aber nicht die code Zeile für Zeile auszuführen, in einem Fall wie diesem, in der die explosion auslösen würde, dann sparen Sie auftreten würde, während es stattfindet? Der Delegat-Aufruf, hier kann man sich etwas Zeit nimmt zu, aber die gleiche Frage gilt, warum wäre es wichtig, wenn es nach diesen Zeilen code?
EDIT: Bin ich zu Recht sagen, dass der main-thread blockiert wird, bevor die Partikel angezeigt werden, indem Sie die folgenden Zeilen von code, d.h. die UI kann sich nicht selbst aktualisieren?
Hier ist mein code:
//Particle animation
LikeExplosion *likeExplosionView = [[LikeExplosion alloc] initWithFrame: CGRectMake(0, 0, 320, 400)];
[likeExplosionView setUserInteractionEnabled: NO];
[self.view addSubview: likeExplosionView];
[self.view bringSubviewToFront: likeExplosionView];
[likeExplosionView decayOverTime: 1.1];
//Delegate call to reload tableview elsewhere
[self.delegate detailViewControllerDidLikeLine];
//Update current object
[_selectedLine setIsLiked: [NSNumber numberWithBool: YES]];
[_selectedLine setIsDisliked: [NSNumber numberWithBool: NO]];
//Update context
NSError *error;
if (![[[CDManager sharedManager] managedObjectContext] save:&error]) NSLog(@"Saving changes failed: %@, %@", error, [error userInfo]);
Erste Frage: warum gibt es eine Verzögerung, wenn ich den Aufruf der animation erste code in der Methode?
Zweite Frage: würde, setzen die save
Anruf auf einem hintergrund-thread, der das problem lösen, und ist es auch sicher /ein gute Idee dies zu tun?
Ich habe kein threading in der app auf alle derzeit definitiv nicht auf einem hintergrund-thread.
InformationsquelleAutor Luke | 2013-04-10
Du musst angemeldet sein, um einen Kommentar abzugeben.
Animationen, und in der Regel nichts zu tun haben mit der UI erfolgt auf der Haupt-thread. Wenn Sie nicht möchten, dass die Persistenz auf der Festplatte (sichern), um Ihre UI (Haupt-thread), die Sie benötigen, um setzen Sie den Rahmen auf eine eigene private queue über
NSManagedObjectContext
'sinitWithConcurrencyType:
Methode. Die private Warteschlange kümmert sich um alle hintergrund-threads, die mit dem Kontext für Sie. Die drei Arten sind:Würden Sie wollen
NSPrivateQueueConcurrencyType
.Nehmen Sie sich ein komplexer Architektur-route durch mit Kind/verschachtelte verwaltete Objekt Kontexten mit verschiedenen concurrency-Typen, aber wenn Sie ein neues Core-Daten-stick mit einem einzigen Rahmen, bis Sie ein fundiertes Verständnis der Zusammenhänge und Warteschlangen.
NSManagedObjectContext
(das passiert nur einmal, beim ersten Start der app), würde ich es initialisieren mit dieser Art, dann jedes mal, wenn er an anderer Stelle verwendet, Sie verwenden einen hintergrund-thread (oder PrivateQueue)?Ja, es würde verwenden Sie es auf eigene queue, daher nicht blockieren UI und handling off-shot threads intern.
Auch, stellen Sie sicher, dass Sie den Kontext
performBlock:
oder `performBlockAndWait: "auf der save-Methode. Dadurch wird sichergestellt, thread-Sicherheit mit Ihrem Kontext.InformationsquelleAutor Gobot
1) die animation wird nicht gestartet, bis das main runloop den kompletten Zyklus. dieser Zyklus wird nicht abgeschlossen, als
save:
ist eine blockierende Methode.2) Verschieben Sie Ihre Daten auf einem hintergrund-thread das Problem lösen wird, aber Sie müssen Zugriff auf die wichtigsten
managedObjectContext
im main-thread, also müssen Sie entweder verwenden Sie einen hintergrund:Könnten Sie in der Lage sein, um die animation zu starten ohne sich zu bewegen, um den hintergrund durch die Planung das speichern auf dem Haupt-thread in den nächsten runloop mit:
[self performSelectorOnMainThread:@selector(saveMain) withObject:nil waitUntilDone:NO];
InformationsquelleAutor Dan Shelly
Check-out diese tolle Artikel CIMGF.com! 😉
Nach dem Lesen des Tutorials sollten Sie wissen, wie man mit diesem problem.
InformationsquelleAutor Nenad M