mikeash.com: just this guy, you know?

Posted at 2009-09-11 21:27 | RSS feed (Full text feed) | Blog Index
Next article: The iPhone Development Story: One Year Later
Previous article: Friday Q&A 2009-09-11: Intro to Grand Central Dispatch, Part III: Dispatch Sources
Tags: gcd rant
GCD Is Not Blocks, Blocks Are Not GCD
by Mike Ash  

There's a lot of discussion going around the internet lately about blocks and Grand Central Dispatch. They're both great new technologies that have seen the light of day with the 10.6 release, and they see a lot of use together. However, a lot of the people discussing blocks and GCD don't seem to understand that they are not, in fact, the same thing, and aren't even really related. I just wanted to make a quick note here to describe exactly what each one is, how they're different, and how they work together.

Blocks
Blocks are a new C/C++/Objective-C language feature designed and developed by Apple. They were first released to the public as part of the clang project. This summer saw a nice packaged blocks-capable compiler in the form of PLBlocks, and they gained official Apple support in 10.6.

Blocks are what other languages commonly call lambdas or closures. They are anonymous inner functions which capture enclosing scope and which can live beyond the lifetime of that enclosing scope. In essence, they allow writing inline code which can then be passed to other functions or modules instead of being executed immediately.

Blocks are officially supported by Apple on 10.6 and up. Programs targeting 10.5 can use blocks if they use PLBlocks. Programs written for other platforms can probably use blocks if they are compiled with clang, but I'm not certain on the status of this work.

Grand Central Dispatch
GCD, also known as libdispatch, is a Mac OS X multiprocessing framework new in 10.6. Its major feature is an efficient system-aware thread pool implementation. "System-aware" means that it will automatically and dynamically scale the number of threads in the pool in response to system load, the number of CPU cores in the computer, and the state of the threads currently executing in the pool. GCD also offers other multiprocessing features such as an events system and semaphores.

As of this week, the GCD is now open source. The system awareness of GCD requires kernel integration which may make it more difficult to port to other platforms, and for now GCD remains a purely Mac OS X 10.6 library.

Why the Confusion?
Reading the above, I think that anyone can see that these two entities are very different. They really have nothing in common. So why is there so much confusion about what's what?

The answer is pretty simple: GCD is built around callbacks. You pass it a callback for an event trigger, or to execute a work unit, or as a cancellation handler, or for many other things.

Callbacks in C have always been clunky. Blocks make callbacks much easier to use. Since GCD is so heavily based on callbacks, the solution was easy: add blocks-based APIs to GCD. Thus, most GCD examples you see out there include blocks as well, as in this example from the dispatch_async man page:

     dispatch_async(my_queue, ^{
             // critical section
     });
The confusion is understandable, but it's important to understand the distinction between the two. You can use blocks without GCD, and in fact many new blocks-based Cocoa APIs in 10.6 do just that. You can use GCD without blocks, via the _f variants provided for every GCD function that takes a block. They go great together, but they are in fact completely different technologies.

And now you know the rest of the story.

Did you enjoy this article? I'm selling whole books full of them! Volumes II and III are now out! They're available as ePub, PDF, print, and on iBooks and Kindle. Click here for more information.

Comments:

My understanding is that the “standard” Clang blocks runtime (compiler-rt) currently works under Mac OS X and Windows. The new/in-development <a href="http://etoileos.com/news/archive/2009/09/10/1744/">GNUstep Objective-C runtime</a> (distinct from the GNU runtime) has its own implementation of blocks.

Interestingly, David Chisnall of GNUstep/Étoilé is a significant driving force in Clang’s Objective-C support, and he’s pushing for <a href="http://lists.cs.uiuc.edu/pipermail/cfe-dev/2009-September/006378.html">improvements</a> to blocks such as runtime type introspection (a glaring omission which I’m glad to see being addressed).
Thanks for the great series of articles on GCD.

I know I need to read through again as I still quite new to OSX programming but a couple of questions.
How does GCD and Blocks fit with Cocoa? For example are NSOperation and NSOperationQueue using GCD under the hood?
Which new cocoa Block api are you referring to?
My understanding is that NSOperation and NSOperationQueue will use GCD underneath on Snow Leopard systems, although I presume you sacrifice a level of control in doing so.
Yes, NSOperationQueue is implemented using GCD on 10.6. There's no real control to be sacrificed, here: NSOpQ is already a high-level API that gives you little control as it is.

Otherwise, GCD basically doesn't fit with Cocoa. You can use them together, certainly, but there's no integration between them. No Cocoa APIs take GCD blocks or return GCD sources or anything like that. This is fine, really: GCD is a perfectly usable and straightforward API as it is, and doesn't need an ObjC wrapper.

As for Cocoa blocks APIs, pop open Xcode and do a multi-file find "In Framework" for (^) and you'll see them all.
Can you provide an example where GCD doesn't use blocks. Providing yet another example of GCD using blocks does not prove your point.
"You can use GCD without blocks, via the _f variants provided for every GCD function that takes a block."

The documentation is freely available. Go look it up!

Comments RSS feed for this page

Add your thoughts, post a comment:

Spam and off-topic posts will be deleted without notice. Culprits may be publicly humiliated at my sole discretion.

Name:
The Answer to the Ultimate Question of Life, the Universe, and Everything?
Comment:
Formatting: <i> <b> <blockquote> <code>.
NOTE: Due to an increase in spam, URLs are forbidden! Please provide search terms or fragment your URLs so they don't look like URLs.
Code syntax highlighting thanks to Pygments.
Hosted at DigitalOcean.