Getting Started With GCD in MacRuby & Rubymotion
Grand Central Dispatch
Grand Central Dispatch is the apple way to perform concurrent programming, by using it you’re able to divide your program into peaces tasks that can be executed by a queue concurrently or serially. Since GCD is a low level C API, you can’t communicate directly with it, but MacRuby has a wrapper for that.
What are Queues?
You can think of Dispatch::Queues as workers waiting to execute undefined tasks, the can either execute tasks concurrently or serially. A Serial Queue executes a single task at once, a concurrent queue is capable to execute as many tasks simultaneously as your system allow it execute.
Creating and Managing Queues:
GCD comes with three different types of queues:
1) The Main queue: the main queue is the application aka. main thread, you can get this queue by using:
1
|
|
2) Global / Concurrents queue: on pre Lion / iOS5 version of GCD there were only one concurrent queue that could have three defined priorities, but now this changed. You can create as much concurrent queues as you want that execute multiple blocks at the same time¹.
1 2 3 4 |
|
3) Customized queues: are lightweight list of blocks which can be executed one at a time in FIFO order, they can be compared with Ruby mutex or traditional ruby thread. They are perfectly suited for synchronization mechanism without have to deal with lock and unlock.² If you want to ensure that tasks execute in a predictable order, you should use the customized queues.
1
|
|
Submitting blocks to queues:
There are two ways to submit a block to a queue, the first is the asynchronous execution, which submits a block to a queue and returns immediately. e.g:
1 2 |
|
The second method is the Dispatch::Queue#sync which submits a block on a dispatch queue and waits until that block completes. Unlike the Dispatch::Queue#async method, the block are synchronously executed. e.g:
1 2 |
|
Submitting blocks later:
Dispatch::Queue#after submits a block asynchronously to the given queue after the given delay (in seconds) is passed.
1
|
|
Concurrently executing one block many times
Dispatch::Queue#apply submits a block to a dispatch queue for multiple execution, if the execution queue is a concurrent, the block will be executed concurrently.
1 2 3 4 |
|
Managing Dispatch Objects
Dispatch Objects allow to manage the blocks execution by canceling, suspend and resume it.
Suspending and resuming execution:
1 2 3 4 5 |
|
Getting the internal Queue Object:
Sometimes when dealing with Cocoa / CocoaTouch API’s you will need to have access to the Queue object, for this purpose Macruby’s GDC-Wrapper delievers a method to get the queue object: Dispatch::Queue#dispatch_object
Dispatch Constants
Dispatch::TIME_FOREVER: means infinity, queue or semaphore will wait till blocks are done
Dispatch::TIME_NOW: means zero, queue or semaphore will not wait for blocks at all
Coming next
Dispatch Barrier
Dispatch Group
Dispatch Semaphore
Dispatch Source
Recommendation:
- An Introduction to GCD with MacRuby by Patrick Thomson
-Intro to Grand Central Dispatch, Part I: Basics and Dispatch Queues by Mike Ash
² the queue names/labels are meant to help you debugging your application, and it should follow the reverse-DNS style convention