Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is kind of a long answer, but the short version is that what you're doing is totally fine and thread safe since you've forced the important part of the operation to run on the main thread.</p> <p>Your first question was, "What happens if I add a concurrent operation in a NSOperationQueue?" <a href="http://developer.apple.com/library/ios/#qa/qa1712/_index.html" rel="nofollow noreferrer">As of iOS 4</a>, <code>NSOperationQueue</code> uses GCD behind the scenes. When your operation reaches the top of the queue, it gets submitted to GCD, which manages a pool of private threads that grows and shrinks dynamically as needed. GCD assigns one of these threads to run the <code>start</code> method of your operation, and guarantees this thread will never be the main thread.</p> <p>When the <code>start</code> method finishes in a concurrent operation, nothing special happens (which is the point). The queue will allow your operation to run forever until you set <code>isFinished</code> to <code>YES</code> and do the proper KVO willChange/didChange calls, regardless of the calling thread. Typically you'd make a method called <code>finish</code> to do that, which it looks like you have.</p> <p>All this is fine and well, but there are some caveats involved if you need to observe or manipulate the thread on which your operation is running. The important thing to remember is this: <em>don't mess with threads managed by GCD</em>. You can't guarantee they'll live past the current frame of execution, and you definitely can't guarantee that subsequent delegate calls (i.e., from <code>NSURLConnection</code>) will occur on the same thread. In fact, they probably won't.</p> <p>In your code sample, you've shunted <code>start</code> off to the main thread so you don't need to worry much about background threads (GCD or otherwise). When you create an <code>NSURLConnection</code> it gets scheduled on the current run loop, and all of its delegate methods will get called on that run loop's thread, meaning that starting the connection on the main thread guarantees its delegate callbacks also happen on the main thread. In this sense it's "thread safe" because almost nothing is actually happening on a background thread besides the start of the operation itself, which may actually be an advantage because GCD can immediately reclaim the thread and use it for something else.</p> <p>Let's imagine what would happen if you didn't force <code>start</code> to run on the main thread and just used the thread given to you by GCD. A run loop can potentially hang forever if its thread disappears, such as when it gets reclaimed by GCD into its private pool. There's some techniques floating around for keeping the thread alive (such as adding an empty <code>NSPort</code>), but they don't apply to threads created by GCD, only to threads you create yourself and can guarantee the lifetime of.</p> <p>The danger here is that under light load you actually can get away with running a run loop on a GCD thread and think everything is fine. Once you start running many parallel operations, especially if you need to cancel them midflight, you'll start to see operations that never complete and never deallocate, leaking memory. If you wanted to be completely safe, you'd need to create your own dedicated <code>NSThread</code> and keep the run loop going forever.</p> <p>In the real world, it's much easier to do what you're doing and just run the connection on the main thread. Managing the connection consumes very little CPU and in most cases won't interfere with your UI, so there's very little to gain by running the connection completely in the background. The main thread's run loop is always running and you don't need to mess with it.</p> <p>It is possible, however, to run an <code>NSURLConnection</code> connection entirely in the background using the dedicated thread method described above. For an example, check out <a href="https://github.com/tumblr/JXHTTP/" rel="nofollow noreferrer">JXHTTP</a>, in particular the classes <a href="https://github.com/tumblr/JXHTTP/blob/master/JXHTTP/JXHTTPOperation.m" rel="nofollow noreferrer">JXOperation</a> and <a href="https://github.com/tumblr/JXHTTP/blob/master/JXHTTP/JXURLConnectionOperation.m" rel="nofollow noreferrer">JXURLConnectionOperation</a></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload