1

We're using dataWithContentsOfURL because it is, uh, simple...

NSData *datRaw = [NSData dataWithContentsOfURL:ur];

Now, of course, that will hang the main UI thread.

So we put it on another thread. We do that exactly thus,

-(void)performSearch:(NSString *)stuff then:(void(^)(void))after
 {
  dispatch_queue_t otherThread =dispatch_queue_create(nil,0);
  dispatch_queue_t mainThread =dispatch_get_main_queue();
  dispatch_async(otherThread,
    ^{
    self.resultsRA = [self ... calls dataWithContentsOfURL ...];

    dispatch_async(mainThread, ^{  if (after) after(); });
    });
 }

(Incidentally, here's an excellent introduction to that if needed https://stackoverflow.com/a/7291056/294884).

Well now, Apple says you should not use dataWithContentsOfURL, they say you should instead just use NSSession. So, dataTaskWithURL:completionHandler:

My question, is there any difference at all between making our own thread (i.e. with dataWithContentsOfURL) versus using dataTask ?

Are we wrong to use dataWithContentsOfURL: on a thread, for some reason? I appreciate it is more convenient, etc. I mean is there are real difference, any dangers, etc.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
Fattie
  • 27,874
  • 70
  • 431
  • 719

2 Answers2

2

One reason to prefer true async io over threaded synchronous io is that threads are not free memory-wise. It's not a huge deal in general but you can save a little memory in your app and (more importantly) a little wired memory in the OS's kernel by not keeping a thread sitting around doing nothing while it waits.

Catfish_Man
  • 41,261
  • 11
  • 67
  • 84
  • HI @Catfish - thanks for that: but I don't understand: are you saying **dataTaskWithURL:completionHandler:** provides true async-io; or are you saying the other approach using **dispatch_async** provides true async-io? Thanks! – Fattie Sep 29 '14 at 06:13
  • dataTaskWithURL:completionHandler: *should* avoid blocking a thread. If it doesn't, that's Apple's bug to fix. dispatch_async + blocking IO will block a thread. – Catfish_Man Sep 29 '14 at 06:30
  • Hi Catfish, thanks again. Hmm, just to be clear .. when you use dispatch_async to ANOTHER THREAD (so: "otherThread = dispatch_queue_create(nil,0)") that will definitely not block the UI. But are you saying using dispatch_async-to-ANOTHER-THREAD could in fact block that thread (NOT THE UI THREAD, THAT OTHER THREAD), potentially wasting some memory for awhile? Thanks!! – Fattie Sep 29 '14 at 06:34
  • Right. A dispatch queue will use zero (if idle), one (serial), or up to 64 (concurrent) threads to do work dispatched to it. What you do once a thread is assigned to your block is pretty much up to you; if you do blocking io it'll hang out waiting until you're done (and if you're on a concurrent queue with <64 worker threads it'll spin up a new one to keep going). – Catfish_Man Sep 29 '14 at 06:41
  • Thanks again. (In short, it's probably generally much better, really, to just use dataTaskWithURL:completionHandler: at all times, pretty much - it seems to me.) – Fattie Sep 29 '14 at 06:44
  • Sent a small courtesy bounty, thanks @Catfish_man ! Hey, 17k – Fattie Oct 01 '14 at 04:33
  • I think the other answer might have been more deserving, but thank you. Glad I could help :) – Catfish_Man Oct 01 '14 at 06:02
1

Some of reasons I can see:

  • With synchronous request you can't know download progress and can't resume download. If you download big file and it fails on 99%, you will need to redownload whole file.

  • As Apple states "Do not use this synchronous method to request network-based URLs. For network-based URLs, this method can block the current thread for tens of seconds on a slow network...". If you are using GCD, you won't directly control the thread you are given and it may block some other important operations on that thread, dataTask scheduler may have better overview of system resources. If you create thread manually, you may overload system(if there is already resource strain at least) with this blocked thread.

  • Also there is "added ability to support custom authentication and cancellation" in dataTaskWithURL:.

  • You may need to customize request headers/body. Maybe it falls in "convenience" category, but anyway it's another thing.

Timur Kuchkarov
  • 1,155
  • 7
  • 21
  • I thought about 1 more reason - Apple can't know who is writing code at the moment, and with synchronous network request it's easy for novice programmer to overlook the nesessity of dispatching this call to another thread, so UI will stall. Also you'd either have to be very attentive not to forget this dispatching or create "wrapper" for this and use it(and pay price for additional calls, which is most probably not noticable, but if you can avoid it with minimal to no work - why not). – Timur Kuchkarov Aug 06 '14 at 08:06