switching to blocks made my programs a lot more modular and flexible. For example in most cases I stopped relying on delegation, I instead pass a block (which encapsulates the variables in the parent object) and it gets the work done in a one way fashion.
In general I think that using blocks helps decouple your code (and I find using them applicable to many design patterns). Here is an example:
/*
* here block is basically is clean up code that is supposed to execute
* after this method finishes its work
*/
-(void)doSomeProcess:(void(^)(void))block {
// do stuff
// ..
// and when you're done
block();
}
// caller 1
[self doSomeProcess:^{
// block body:
// dismiss UI
}];
// caller 2
[self doSomeProcess:^{
// another block body:
// do business logic clean up
// dismiss UI
}];
and so many objects or callers can be calling the doSomeProcess
method, but each having their own clean up work.
another example: here is another example (I literally just did it so I figured I could share it with you).. look at this unit test with KIF:
[sr performFilterAttachmentWithBlock:^(NSArray *fileBucketResults){
for (NSMutableDictionary* fileBucketResult in fileBucketResults) {
[elementsToAdd addObject:fileBucketResult];
[rowsToAdd addObject:[NSIndexPath indexPathForRow:cellIndex inSection:0]];
cellIndex++;
}
// note this notification
[[NSNotificationCenter defaultCenter]
postNotificationName:(NSString *)kFileBucketSubviewFetchedResultsFromDB
object:fileBucketResults];
} withQuery:query sortBy:(NSString *)kFileBucketSortBySenderName];
in KIF unit testing, there are some unit tests that rely on sending notifications.. prior to using blocks (and while using delegates).. i had to mix in testing code inside my actual code (ie this notification was actually placed in my main code).. but now thanks to blocks.. i can just put all my testing code inside a block, which in turn is placed in my unit test file (ie doesn't mix with main code).. = cleaner code! :)
another example: it makes for a nice way to hide some very specific utility/helper functions, which reduces namespace cluttering and make for cleaner code overall.. ex:
// without blocks
-(void)someMethod {
// call this private method that does some helper stuff
[self helperMethod];
// we call the helper method several times in this f'n
[self helperMethod];
}
-(void)helperMethod {
// this method is only useful for 'some method'
// although it's only visible within this class.. it's still
// an extra method.. also nothing makes it obvious that
// this method is only applicable to 'someMethod'
..
}
// With blocks
-(void)someMethod {
void(^helperMethod)(void) = ^{
// helper block body
// this block is only visible to 'some method'
// so it's obvious it's only applicable to it
}
// call helper method..
helperMethod();
// .. as many times as you like
helperMethod();
}
here is a question/answer that illustrates converting a delegation method to a block..