I see two common patterns for blocks in Objective-C. One is a pair of success:/failure: blocks, the other is a single completion: block.
For example, lets say I have a task that will return an object asynchronously and that task might fail. The first pattern is -taskWithSuccess:(void (^)(id object))success failure:(void (^)(NSError *error))failure
. The second pattern is -taskWithCompletion:(void (^)(id object, NSError *error))completion
.
success:/failure:
[target taskWithSuccess:^(id object) {
// W00t! I've got my object
} failure:^(NSError *error) {
// Oh noes! report the failure.
}];
completion:
[target taskWithCompletion:^(id object, NSError *error) {
if (object) {
// W00t! I've got my object
} else {
// Oh noes! report the failure.
}
}];
Which is the preferred pattern? What are the strengths and weaknesses? When would you use one over the other?
Best Answer
Completion callback (opposed to success/failure pair) is more generic. If you need to prepare some context before dealing with return status, you can do it just before "if (object)" clause. In success/failure case you have to duplicate this code. This depends on callback semantics, of course.