4

In the Apple Docs, it says:

It’s best practice to use only one block argument to a method.

Is it ok to pass multiple block arguments; or should this be avoided?

Specifically here are a few options I'm working with (I'm hoping to use the first one):

-(void) doSomethingWithSuccessBlock:(void(^)(void))successBlock withFailureBlock:(void (^)(NSError *)) failureBlock

OR

-(BOOL) didDoSomethingWithFailureBlock:(void (^)(NSError *)) failureBlock

OR

-(void) doSomethingWithCallbackBlock:(void (^)(BOOL, NSError *)) callbackBlock
1
  • 4
    The document you quote answers your question :) Best practice is to only pass one block (and usually as the last parameter, mostly I believe this is because formatting and legibility suffers otherwise. That said, it is common (particularly for success/failure blocks) to have methods that take two blocks. Apple has examples in UIView(UIViewAnimationWithBlocks) and elsewhere, so it's certainly allowable. "Best Practice" doesn't mean you have to do it this way, it means if you're not doing it this way you need to think about why? Commented May 2, 2014 at 15:51

4 Answers 4

8

Using more than one block as a parameter will warp your mind, curve your spine, and make the enemy win the war. (to paraphrase George Carlin)

Kidding aside, it's a good goal to only have 1 block parameter, but as others have pointed out, Apple has a number of classes who's methods take multiple blocks. Before designing an API that uses multiple block parameters, spend some time thinking about alternatives, and pondering what it does to readability and maintainability of your code. Is there a simpler way to accomplish the same goal? If multiple blocks is the cleanest way to accomplish your goal, then use it.

I think your example of a method that takes both a success block and a failure block is pretty reasonable. You could refactor it into a single block that takes a BOOL parameter "success" and interrogate that parameter in the block to decide what to do. (the CAAnimation delegate method animationDidStop:finished: uses this approach. Actually, so does the completion block in UIView animation, come to think of it.)

You'll have to decide if that makes the method and the blocks you pass to it simpler and cleaner or more complex.

Sign up to request clarification or add additional context in comments.

Comments

0

Yes; the success/failure block semantic is already being used by AFNetworking, so it's OK for sure.

Comments

0

As iOS SDK uses several block parameters in method then it's okey to implement your custom code in such way.

iOS standard method with 2 block parameters example:

[UIView animateWithDuration:animationDuration animations:^{

} completion:^(BOOL finished) {

}];

Comments

0

I don't mind multiple blocks; however, using multiple blocks like this tends to make me extremely frustrated. Some will disagree, but if I'm sending an operation, I don't want two separate answers, I want one answer with the information I need. Don't send success/error, just include an error value if there was an error. With that said, for things like animation and completion, there are cases where it's beneficial.

I'd really prefer dealing with something like this:

-(void) doSomethingWithCompletionBlock:(void(^)(NSError *))completionBlock;

Then:

[self doSomethingWithCompletionBLock:^(NSError * error) {

    if (!error) {
        // Success  
    }
    else {
        // Failure 
    } 

}];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.