I was recently asked by a .NET developer what exactly blocks in Obj-C are so here is a quick overview.

Blocks are a non-standard extension added to Obj-C, C++ and C languages by Apple, and bare a similar resemblance to GCC nested functions. They are incredibly powerful at first glance to the extent that a lot of junior developers will be quick to overuse them in place of more solid call-back or reactive design patterns.

To put it simply they are similar to closures or lambdas in that they are distinct segments of code that can be passed to a method or function as a value, to be executed at any later time by calling it using the same syntax that would be used for calling a function.

^{
    NSLog(@"%@", @"This is a block");
}
^(id first, int secondValue){
    NSLog(@"%@", @"This is a block with arguments");
}
^NSString*(double firstValue, double secondValue) {
    return @"This is a block with arguments and a return type";
}
void (^simpleBlock)(void) = ^{  
    NSLog(@"%@", @"Declaring, defining and invoking a block");
};
simpleBlock();  

The syntax differs depending on the context and can look odd at first, second and more glances, so I highly recommend bookmarking the safe for work link to f******blocksyntax.com : http://goshdarnblocksyntax.com/

Blocks allow us to define callbacks for methods in-line with where they are called from - this can be very handy for asynchronous callbacks, or scheduling code on another thread (they were initially conceived for interaction with the Grand Central Dispatch API. Here are two excellent examples in the Cocoa API:

@interface NSOperationQueue
...
- (void)addOperationWithBlock:(void (^)(void))block;
...
@end
@interface NSURLConnection
...
+ (void)sendAsynchronousRequest:(NSURLRequest *)request
                          queue:(NSOperationQueue *)queue
              completionHandler:(void (^)(NSURLResponse *response,
                                          NSData *data,
                                          NSError *connectionError))handler;
...
@end
The important bit!

As great as blocks are, there are some important facts about blocks to be aware of:

  • You need to make a copy when you expect the block to be used after destruction of the scope within which it was declared. In practice, this normally only applies to assigning a block to a property; under ARC this is done automatically but it's good practice to specify copy as an attribute.
  • Blocks will retain strong references to any captured objects, including self, which means that it’s easy to end up with a strong reference cycle. This will be touched on in a future article.
  • The code inside a block will be invoked on the thread from which it was invoked, not where it was defined or passed. This means careful consideration must be taken to read the documentation for any unknown APIs when used as method parameters as some may always be invoked on the main queue/thread, some may be invoked on a queue/thread specified by a property on the receiver and others may have no regard whatsoever.