2012-04-01 11 views
5

Tengo un problema básico al sincronizar openWithCompletionHandler: (UIManagedDocument) con las actividades principales.iOS5.1: tareas de sincronización (aguarde la finalización)

Situación: Tengo una clase singleton que administra un UIManagedDocument compartido. Esta clase proporciona un método que debe entregar el documento en un estado normal (es decir, crearlo o abrirlo, lo que sea necesario). Pero debido a que openWithCompletionHandler: realiza su trabajo principal de forma asincrónica en segundo plano, mi programa debería esperar con la configuración de los fetchedResultsController hasta que el documento esté realmente abierto. El método "viewWillAppear" (actualmente) no produce resultados útiles cuando la base de datos no está lista. Esperar estaría bien para mí, pero ser notificado probablemente sería la mejor manera. Tal vez viewWillAppear resulta no ser el punto correcto para setupFetchedResultsController porque no se llamó en un runloop.

¿Hay un patrón estándar para lograr esto?

Poco más de fondo (no tan importante, supongo) Estoy trabajando en una pequeña aplicación iOS 5.1 que implica un CoreData UIManagedDocument. Me parecí al ejemplo de la Lección 14 del curso de Stanford del otoño pasado en iTunes-U. Todo funcionaba bien hasta que traté de separar el manejo del UIManagedDocument de la clase UITableViewController en una clase separada que manejaba mi documento. En la versión original, FetchedResultsController se configuró en el controlador de finalización.

Respuesta

3

Sugiero seguir la excelente publicación de Justin Driscoll en Core Data with a Single Shared UIManagedDocument.

Encontrará un informe completo sobre UIManagedDocument singleton y un ejemplo sobre performWithDocument. Su código de configuración fetchedResultsController debería ir realmente en el bloque performWithDocument:^{}.

También tenga en cuenta que openWithCompletionHandler no es seguro para subprocesos: las invocaciones simultáneas de performWithDocument al abrir el documento provocarán un bloqueo. La solución para mí no era trivial (y bastante específica de la aplicación), así que si se encuentra con el mismo problema, le sugiero que busque en UIDocumentStateChangedNotification que notifica los cambios de estado del documento y puede ser su punto de sincronización para varios abridores de documentos.

Algunos fragmento si está interesado,

Primero en init del MYDocumentHandler, configurar una notificación adicional al final:

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

Luego, en performWithDocument, @synchronized (self.document) en la abierta crítica/secciones de creación para asegurarse de que solo entre un subproceso a la vez, y bloquee más subprocesos hasta que la apertura/creación sea exitosa.

último añadir la siguiente función:

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

En cuanto a los hilos de desbloqueo de bloque /, YMMV. Usé un dispatch_semaphore_t junto con algunas dispatch_queues para satisfacer los requisitos específicos de la aplicación. Su caso podría ser tan simple como esperar completarlo o descartar otros hilos.

Cuestiones relacionadas