Using iOS GCD and NotificationCenter to alert user when asynch data load is complete (async load of several datasets one at a time)

StackOverflow https://stackoverflow.com/questions/14048335

Pregunta

I am writing an iPad App in which I load data for a multi-storied building asynchronously. I have set up NSNotifications to alert the user once data-load for all floors is complete.

The data load for each floor is kicked off in a loop when a load button is pressed in ChildViewController (a popup VC)

ChildViewController is launched from ParentViewController.

I add an observer in ChildViewController for a notification named "dataloaded" and set up a handler function childDataLoaded to handle the notification.

Since ChildViewController may be dismissed before the data load is completed I also have a observer and handler (parentDataLoaded) setup in ParentViewController to handle the same "dataloaded" notification.

I have implemented the data load function 'parseAndSaveData' in AppDelegate. parseAndSaveData is invoked when the ChildViewController button is clicked. It takes as parameter the floor identifier (NSString). It calls a web-service to get data for that floor and loads this data into the database. The webservice is quick but adding the data to the sqllite database takes a longer time (I am using Core data). I therefore invoke this dataload part using a dispatch_asynch call (since this is the most time consuming part).

The dataload portion when complete posts the "dataloaded" notification.

I expect this notification to invoke either the handler in ChildViewController or in ParentViewController (whichever is active when the notification is posted)

The problem I have is that the notification is unpredictable and I see only one of the handlers (the one in ChildViewController) getting invoked and it gets invoked for only one of the floors, despite the fact that all floors get loaded successfully.

Any advise on the above design and implementation or alternatives would be most appreciated!

ADDING CODE FOR THE dispatch_group suggestion from @Samuel

Confirm action on my popup VC kicks off the following…
   creates a a GCD dispatch_group, floorDataGroup                    
   creates a GCD dispatch_queue, floorDataQueue, using dispatch_get_global_queue  
   with default priority

   loops over floors in building and for each floor  {
    dispatch_group_async(floorDataGroup, floorDataQueue, ^{  
              // start dispatch_group_async block
      //gets rooms details for the building and floor as follows:
      Calls webservice (using AFNetworking Library) to get room details, 
              which on success executes a block
        ( ^{
              Parses the XML, extracts room data 
                          Inserts room data into Core Data/sqllite table
           }); //end web service success block

    }); //end dispatch_group_async block
} //end loop over each floor

   dispatch_group_notify(floorDataGroup, floorDataQueue, ^{  
       //start dispatch_group_nbotify block
       create alert (UIAlert) with message “All floors loaded” 
       and an OK button to dismiss the alert
    [alert show]
    }
¿Fue útil?

Solución

I would consider using NSOperationQueue... from Apple GCD Docs

GCD is not restricted to system-level applications, but before you use it for higher-level applications, you should consider whether similar functionality provided in Cocoa (via NSOperation and block objects) would be easier to use or more appropriate for your needs. See Concurrency Programming Guide for more information.

Specifically look at using NSBlockOperation. You can add each request for data in a separate execution block with addExecutionBlock:. Then set your completion block with setCompletionBlock:. Make sure that your completion block is fired on the main thread.

If you must use GCD then I would recommend looking at groups.

stackoverflow related questions with good answers:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top