Objective-c – Asynchronous vs Synchronous vs Threading in an iPhone App

cocoa-touchiphonemultithreadingobjective crest

I'm in the design stage for an app which will utilize a REST web service and sort of have a dilemma in as far as using asynchronous vs synchronous vs threading. Here's the scenario.

Say you have three options to drill down into, each one having its own REST-based resource. I can either lazily load each one with a synchronous request, but that'll block the UI and prevent the user from hitting a back navigation button while data is retrieved. This case applies almost anywhere except for when your application requires a login screen. I can't see any reason to use synchronous HTTP requests vs asynchronous because of that reason alone. The only time it makes sense is to have a worker thread make your synchronous request, and notify the main thread when the request is done. This will prevent the block. The question then is bench marking your code and seeing which has more overhead, a threaded synchronous request or an asynchronous request.

The problem with asynchronous requests is you need to either setup a smart notification or delegate system as you can have multiple requests for multiple resources happening at any given time. The other problem with them is if I have a class, say a singleton which is handling all of my data, I can't use asynchronous requests in a getter method. Meaning the following won't go:

 - (NSArray *)users {
     if(users == nil)
        users = do_async_request // NO GOOD

     return users;
 }

whereas the following:

 - (NSArray *)users {
    if(users == nil)
      users == do_sync_request // OK.

    return users;
 }

You also might have priority. What I mean by priority is if you look at Apple's Mail application on the iPhone, you'll notice they first suck down your entire POP/IMAP tree before making a second request to retrieve the first 2 lines (the default) of your message.

I suppose my question to you experts is this. When are you using asynchronous, synchronous, threads — and when are you using either async/sync in a thread? What kind of delegation system do you have setup to know what to do when a async request completes? Are you prioritizing your async requests?

There's a gamut of solutions to this all too common problem. It's simple to hack something out. The problem is, I don't want to hack and I want to have something that's simple and easy to maintain.

Best Answer

I'm not discounting asynchronous delegate calls, but I usually end up using a threaded worker class with synchronous requests. I find it's easier in the long run to have a well defined, threaded API, instead of filling up your controller with code managing the state between asynchronous methods. You could even make asynchronous in your worker thread, although usually it's easier to use the synchronous methods unless they don't support a feature you need to use. Of course, all of this depends on the circumstances, I can think of many situations where simply using the asynchronous methods would be the best route.

Definitely consider NSOperationQueue if you go this route; it greatly simplifies creating multiple worker threads, and it also supports priorities and dependancies between operations. Right now there are some problems with it on 10.5, but I haven't heard of any issues on the iPhone.