5

I make an app that accesses some data on the first launch and then displays it. I've been downloading this data this way:

NSData *data = [NSData dataWithContentsOfURL:url];

Is this bad? Right now I've set the method that contains this to run in a background thread using GCD, but I heard that since dataWithContentsOfURL is synchronous, it's bad. Are there any opinions on this?

Yep
  • 653
  • 5
  • 20
  • @bryanmac Please use the grand-central-dispatch tag for Apple GCD questions. –  Nov 21 '11 at 04:03

2 Answers2

5

It's bad if you run it on the main UI thread. That will block the responsiveness of your app which is bad but it's even worse on start up.

You need to make it async. You can do that by either running that method on a background thread (GCD dispatch_async) or by using async methods of NSUrlConnection.

Here's an example of using GCD to work in the background and then update the UI (after done) on the main thread:

GCD, Threads, Program Flow and UI Updating

Another option is async method of NSUrlConnection. See the initWithRequest methods here:

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html

Community
  • 1
  • 1
bryanmac
  • 38,941
  • 11
  • 91
  • 99
  • By running it in a background thread using GDC, is that going to be a problem? – Yep Nov 20 '11 at 04:10
  • 1
    I did it this way: `dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //do something });` – Yep Nov 20 '11 at 04:12
  • Should I not be using the global background thread? Should I create one myself? – Yep Nov 20 '11 at 04:17
  • 1
    That's fine - as long as it's async. but, still be careful even if async - hopefully the app paints and is available. If you make it async but you wait for it to be done before you show anything useful, the perception that's it's hanging starting up will still be there - show some UI - show loading ... something. – bryanmac Nov 20 '11 at 04:20
  • the difference between the global queue and creating one yourself depends on how you want to synchronize the queued items in the background. It's a queue so they process 1 after the other 1 but in the bg... – bryanmac Nov 20 '11 at 04:22
  • For example, if you want different sub-systems of your app to be async and synchronized but run in parallel with other sub-systems which do not share data, then you can create your own. global is simple ... – bryanmac Nov 20 '11 at 04:23
3

You're safe as long as you're running it in a background thread.
The idea that synchronous loading is bad is only valid for the main UI thread. A long running operation on the main UI thread will make your app unresponsive. Doing it in the background is the correct way to do this. Also, consider using:

+dataWithContentsOfURL:options:error: 

so that you can get an error back if anything goes wrong.

George
  • 1,457
  • 11
  • 26