iOS5.1: synchronising tasks (wait for a completion)

前端 未结 1 1331
一生所求
一生所求 2021-02-10 11:45

I have a basic problem synchronizing openWithCompletionHandler: (UIManagedDocument) with the main activities.

Situation: I have a singleton class managing a shared UIMan

1条回答
  •  臣服心动
    2021-02-10 12:30

    I suggest following Justin Driscoll's excellent post on Core Data with a Single Shared UIManagedDocument.

    You will find a complete writeup on UIManagedDocument singleton and an example on performWithDocument. Your fetchedResultsController setup code should really go in the performWithDocument:^{} block.

    Also note that openWithCompletionHandler is not thread safe - concurrent invocations of performWithDocument while opening the document will cause a crash. The solution for me was non-trivial (and quite app-specific), so if you run into the same problem, I suggest you looking into UIDocumentStateChangedNotification which notifies document state changes and can be your synchronization point for multiple document openers.

    Some snippet if you are interested,

    First in MYDocumentHandler's init, setup an additional notification at the end:

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

    Then in performWithDocument, @synchronized (self.document) on the critical open/creation sections to make sure only one thread enters at a time, and block further threads until open/creation succeeds.

    Finally add the following function:

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

    As for block/unblocking threads, YMMV. I used a dispatch_semaphore_t along with some dispatch_queues to satisfy app-specific requirements. Your case could be as simple as waiting for completion or dropping other threads.

    0 讨论(0)
提交回复
热议问题