Lessons from iOS dev #2: Delegates are good, blocks are better

One of the core fundamentals of Objective-C is protocols and delegates. Almost every single Objective-C app is likely to use them in some way or another because for many years they have been the ubiquitous way to communicate universally between classes. Whilst they are highly useful and I use them pretty much everywhere, they aren’t always the best solution to the problem.

Keep Calm has two main view controllers (the grid and editing view) and each of them is a delegate for about forty odd different protocols. At least thirty of them are protocols I’ve written myself, rather than Apple ones such as UICollectionViewDataSource. I’ve done a reasonably good job at using #pragma – marks to organise the various methods in the delegates, but the classes are beginning to feel a little bloated.

The new alternative is to use blocks instead. Blocks are essentially an extension of C function pointers. The main benefit is that it massively reduces the amount of code you have to write complete a task:

With a protocol and delegate

@protocol MyClassDelegate

-(void)doSomethingInDelegate;

@end

@interface MyClass : NSObject

@property id<MyClassDelegate> delegate;

-(void)doSomething

@end

@implementation MyClass

-(void)doSomething
{
    [self.delegate doSomethingInDelegate];
}

@end

@interface MyOtherClass<MyClassDelegate> : NSObject
...
@end

@implementation MyOtherClass

-(void)doSomethingInDelegate
{
    NSLog(@"Doing something in delegate");
}

@end

With a block

@interface MyClass : NSObject

-(void)doSomething:(void (^)(void))block;

@end

@implementation MyClass

-(void)doSomething:(void (^)(void))block
{
    block();
}

@end

@implementation MyOtherClass

-(void)begin
{
    [self.myClass doSomething:^(){
        NSLog(@"Doing something in other class");
    }];
}

@end

Obviously the latter example is much shorter and the code is a little easier to read (once you get used to the syntax of blocks). Apple is beginning to use blocks across the Cocoa and Cocoa Touch frameworks for everything from fast iteration to sorting to completion handlers.

There are a lot of cases where blocks aren’t appropriate though – I wouldn’t make a table data source with blocks, for example, because the number of blocks would become ridiculous. In my mind they are best for short snippets of code where they are replacing a protocol that one uses a maximum of two functions. Another disadvantage is that blocks inside blocks produces ridiculously ugly code. Even with only three blocks inside one another my code is comfortably running off the screen in Xcode, which is a pain.

I’ve also got mixed views on how reusable the code produced by blocks is. You are effectively defining functions within functions, which makes it harder to take the source and use it elsewhere because you have to write the block syntax into regular Objective-C function syntax.

Blocks are very useful and its worth learning about them from Apple’s documentation. I’ve only touched on some of the things that you can do with them and I am sure that in the future Apple will carry on introducing them across Cocoa.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s