2

I need to use the standard location service and perform some processing, including some network calls, every location update notified. I need location updates being processed in FIFO order, to keep tracking of the device, and get results as fast as possible. What should be the best way or technique to ensure that locations are processed in order and processing does not overlap (and besides to get a fast response): operation queues, dispatch queues, or threads directly (or even another way, if it exists)? It looks like operation queues and dispatch queues are almost the same, in terms of performance, but dispatch queues seem to be easier to handle, so I don't know what could be the advantages of each one. Regarding threads, I have been discouraged to usually use them, but I don't know if their efficiency over operation/dispatch queues is really noticeable and it is worth to use them.

Thanks in advance

AppsDev
  • 12,319
  • 23
  • 93
  • 186

1 Answers1

1

If you don't want stuff to operate concurrently in the background, then you need a serial queue. To create a serial GCD queue:

dispatch_queue_t queue = dispatch_queue_create("com.appsdev.project1", 0);

And each time you want to add something to that queue, it's simply:

dispatch_async(queue, ^{
    // do your background stuff

    dispatch_async(dispatch_get_main_queue(), ^{
        // update the UI
    });
});

If you want to use NSOperationQueue it's practically as easy:

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;

And to add operations to that serial queue:

[queue addOperationWithBlock:^{
    // do your stuff

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        // update the UI
    }];
}];

And in answer to your NSThread question, I don't see any need for that on the basis of what you've described. Certainly there's no perceptible performance issue.

By the way, is the stuff you're adding to your dispatch/operation queue guaranteed to operating synchronously (i.e. you're not doing geocoding or stuff like that which, itself, operates asynchronously, are you?)? If it operates asynchronously, then additional care must be taken.


By the way, if you only care about the most recent location, using operation queues, you also have to opportunity to cancel other operations that have not yet started by calling:

[queue cancelAllOperations];

The operation in progress will complete first (unless you put in code to test to see if it was canceled), but pending operations that have not yet started can easily be canceled before you initiate a new request based upon the latest location. It just depends upon whether you really want all of the location requests processed serially, or whether you just want to finish the one in progress, clear out the others, and queue a new operation based upon the new location. It just depends upon what your app needs, but frequently you only care about the current location. This can ensure that your queue doesn't get too backlogged.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thanks for replying. I do need to take into account all locations that are notified according to my distance filter and accuracy settings, and regarding their processing, I have a critical section and I'm worried about ensuring that it is executed for each location in the order they are received, and for just one of them at the same time. Since use of threads seem to be discouraged in iOS, I don`t know how to handle that without semaphores. – AppsDev Feb 24 '13 at 09:25
  • My location updates trigger a method that, in its body, in turn calls another method, and so on. Does that way of calling operation/dispatch queues assure that the whole processing of first location will complete before processing the next one? – AppsDev Feb 24 '13 at 09:27
  • @AppsDev It will, _if_ those methods all run synchronously (which, by default, they do). But there are some possibilities implied by your question which might entail asynchronous operations. For example, are you using `CLGeocoder`? Are you using `NSULRConnection` (unless you're using `sendSynchronousRequest`)? Etc. Those are a few examples of asynchronous operations (i.e. things that take so long that Apple kindly provided asynchronous operations, which was kind of them, but just adds a wrinkle to our above solution.) You have to look at that code you plan on calling. – Rob Feb 24 '13 at 13:27
  • If you're dealing with methods that either (a) provide completion blocks; or (b) involve the use of a delegate protocol, then you might be dealing with an asynchronous methods. – Rob Feb 24 '13 at 13:39
  • Thanks! What is the difference between operation and dispatch queues? What should I consider when choosing one of the techniques? – AppsDev Feb 24 '13 at 15:19
  • @AppsDev Functionally they're very similar. In fact, I understand that `NSOperationQueue` uses GCD's dispatch queues behind the scenes, so they're using the same technology. Many people will generally use GCD unless they need some of the operation queue features (like the ability to easily cancel previously queued operations, or set the maximum number of concurrent operations). Since you're dealing with a serial queue and because it doesn't sound like you need the `cancelAllOperations` functionality, GCD's dispatch queues is probably fine for you. – Rob Feb 24 '13 at 16:13