2012-04-01 8 views
5

Ich habe ein grundlegendes Problem beim Synchronisieren von openWithCompletionHandler: (UIManagedDocument) mit den Hauptaktivitäten.iOS5.1: Synchronisierungsaufgaben (Warten auf eine Beendigung)

Situation: Ich habe eine Singleton-Klasse, die ein gemeinsames UIManagedDocument verwaltet. Diese Klasse stellt eine Methode bereit, die das Dokument in einem normalen Zustand liefern soll (d. H. Erstellt oder öffnet es, was auch immer erforderlich ist). Aber weil openWithCompletionHandler: seine Hauptaufgabe asynchron im Hintergrund ausführt, sollte mein Programm mit dem Einrichten der abgerufenenResultsController warten, bis das Dokument wirklich geöffnet ist. Die "viewWillAppear" -Methode (derzeit) produziert keine nützliche Ausgabe, wenn die Datenbank nicht bereit ist. Warten wäre für mich in Ordnung, aber wahrscheinlich benachrichtigt werden, wäre der bessere Weg. Vielleicht ist viewWillAppear nicht der richtige Punkt für setupFetchedResultsController, weil er nicht in einem Runloop aufgerufen wird.

Gibt es ein Standardmuster, um dies zu erreichen?

Etwas mehr Hintergrund (nicht so wichtig, nehme ich an) Ich arbeite an einer kleinen iOS 5.1 App mit einem CoreData UIManagedDocument. Ich ähnelte dem Beispiel aus Lektion 14 vom Stanford-Kurs im letzten Herbst in iTunes-U. Alles funktionierte einwandfrei, bis ich versuchte, die Handhabung von UIManagedDocument von der UITableViewController-Klasse in eine separate Klasse zu verschieben, die mein Dokument behandelte. In der ursprünglichen Version wurde der FetchedResultsController im Completion-Handler eingerichtet.

Antwort

3

Ich schlage vor Justin Driscoll 's hervorragende Post auf Core Data with a Single Shared UIManagedDocument.

Sie finden eine vollständige Beschreibung auf UIManagedDocument singleton und ein Beispiel auf performWithDocument. Der Setup-Code für den hostedResultsController sollte wirklich in den Block performWithDocument:^{gehen.

Beachten Sie auch, dass OpenWithCompletionHandler nicht threadsicher ist - gleichzeitige Aufrufe von performWithDocument beim Öffnen des Dokuments führen zu einem Absturz. Die Lösung für mich war nicht trivial (und ziemlich app-spezifisch). Wenn Sie also auf das gleiche Problem stoßen, schlage ich vor, dass Sie sich in umsehen, das Änderungen am Dokumentenstatus meldet und Ihr Synchronisationspunkt für mehrere Dokumentenöffner sein kann.

Einige Schnipsel, wenn Sie interessiert sind,

Zuerst in MYDocumentHandler init, Setup eine zusätzliche Benachrichtigung am Ende:

[[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(documentStateDidChange:) 
               name:UIDocumentStateChangedNotification 
               object:self.document]; 

Dann in performWithDocument, @synchronized (self.document) auf der kritischen offen/Erstellungsabschnitte, um sicherzustellen, dass immer nur ein Thread gleichzeitig eintritt, und weitere Threads blockieren, bis das Öffnen/Erstellen erfolgreich ist.

Schließlich fügen die folgende Funktion:

- (void)documentStateDidChange:(NSNotification *)notification 
{ 
    if (self.document.documentState == UIDocumentStateNormal) 
     @synchronized (self.document) { 
      ... unblock other document openers ... 
     } 
} 

Wie bei Block/Unblocking Fäden, YMMV. Ich habe einen dispatch_semaphore_t zusammen mit einigen dispatch_queues verwendet, um die anwendungsspezifischen Anforderungen zu erfüllen. Ihr Fall könnte so einfach sein wie das Warten auf die Fertigstellung oder das Löschen anderer Threads.