Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>As Jacob points out, while they may appear the same, they are different things. In fact, there's a significant difference in the way that they handle sending actions to the main thread if you're already running on the main thread. </p> <p>I ran into this recently, where I had a common method that sometimes was run from something on the main thread, sometimes not. In order to protect certain UI updates, I had been using <code>-performSelectorOnMainThread:</code> for them with no problems.</p> <p>When I switched over to using <code>dispatch_sync</code> on the main queue, the application would deadlock whenever this method was run on the main queue. Reading the documentation on <a href="http://developer.apple.com/library/mac/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/c/func/dispatch_sync" rel="noreferrer"><code>dispatch_sync</code></a>, we see:</p> <blockquote> <p>Calling this function and targeting the current queue results in deadlock.</p> </blockquote> <p>where for <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/performSelectorOnMainThread:withObject:waitUntilDone:" rel="noreferrer"><code>-performSelectorOnMainThread:</code></a> we see </p> <blockquote> <p><em>wait</em></p> <p>A Boolean that specifies whether the current thread blocks until after the specified selector is performed on the receiver on the main thread. Specify YES to block this thread; otherwise, specify NO to have this method return immediately.</p> <p>If the current thread is also the main thread, and you specify YES for this parameter, the message is delivered and processed immediately.</p> </blockquote> <p>I still prefer the elegance of GCD, the better compile-time checking it provides, and its greater flexibility regarding arguments, etc., so I made this little helper function to prevent deadlocks:</p> <pre><code>void runOnMainQueueWithoutDeadlocking(void (^block)(void)) { if ([NSThread isMainThread]) { block(); } else { dispatch_sync(dispatch_get_main_queue(), block); } } </code></pre> <p><strong>Update:</strong> In response to Dave Dribin pointing out the <a href="http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/dispatch_get_current_queue.3.html" rel="noreferrer">caveats section on<code>dispatch_get_current_queue()</code></a>, I've changed to using <code>[NSThread isMainThread]</code> in the above code.</p> <p>I then use </p> <pre><code>runOnMainQueueWithoutDeadlocking(^{ //Do stuff }); </code></pre> <p>to perform the actions I need to secure on the main thread, without worrying about what thread the original method was executed on.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

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