+ (void)performRequestWithUri:(NSString *)requestUri params:(NSDictionary *)params completionHandler:(void (^)(NSDictionary *, NSError *))completionBlock
{
    
    // Generate the URL
    NSString *requestUrl = [NSString stringWithFormat:@"http://the.api.com%@", requestUri];
    
    // Create the connection
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:requestUrl]];
    
    // Make an NSOperationQueue
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue setName:@"com.your.unique.queue.name"];
    
    // Send an asyncronous request on the queue
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        
        // If there was an error getting the data
        if (error) {
            
            dispatch_async(dispatch_get_main_queue(), ^(void) {
                completionBlock(nil, error);
            });
            return;
        }
        
        // Decode the data
        NSError *jsonError;
        NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
        
        // If there was an error decoding the JSON
        if (jsonError) {
            
            dispatch_async(dispatch_get_main_queue(), ^(void) {
                
            });
            return;
        }
        
        // All looks fine, lets call the completion block with the response data
        dispatch_async(dispatch_get_main_queue(), ^(void) {
            completionBlock(responseDict, nil);
        });
    }];
}

So, I am working on a little app that front an API back-end I am also writing and have been watching the WWDC 2011 videos on GCD and Blocks... thought I would give all this a go!

It's pretty simple, heres an example request:

[SHAPIController performRequestWithUri:@"/your/api/method" params:nil completionHandler:^(NSDictionary *response, NSError *error) {

            if (error) {
                NSLog(@"%@", error);
            }

            NSLog(@"%@", response);
        }];

The second NSLog will output something like this (of course depending on the API):

{
    some = json;
    yeah =     (
        yeah,
        sdfsdf,
        sdfdsf
    );
}

The completion block will always be called on the main thread so you can update your UI or whatever there.

Hope its useful to someone :)