Should my Block-based API have just completion or both success and failure handlers?

后端 未结 3 1869
闹比i
闹比i 2021-02-02 17:22

When designing a block-based API in ObjC, which approach is better, one completion block or two, one each for success and failure?

Let\'s say we have a method retrieving

3条回答
  •  醉梦人生
    2021-02-02 17:50

    Both are fine patterns (and I up voted both Firo's and John's answers because -- yes, it is a matter of taste and both of their answers are spot on), but there are several distinct advantages to going with a single block, in my experience. John Woods raises an excellent point about the "flavor" of the API, though I would claim that a network operation always completes (unless it has no timeout, which is a different class of bug) and that the success/failure modality is oft not quite either/or.

    • It eliminates having to duplicate the code between the blocks that is common to tearing down the task on completion regardless of success or failure.

    • It provides a single conceptual execution flow between scheduling the task and knowing when the task is completed. When this task is completed, the completion block will be called.

    • In some situations, a failure may actually produce data that should be processed in a fashion like the success path. In fewer situations, a successful completion may actually carry along an error. While the NSError** pattern on methods is purely either/or, one of the advantages of using either block pattern is that this can be expressed. The further advantage of using a single completion block is that you avoid duplicated logic.

    • Multiple blocks as parameters to methods is flat out ugly and annoying. There is a reason why the coding pattern is only pass one block to a method and always make that block the last parameter. Unfortunately, even the system APIs don't consistently follow this pattern, though the use is limited mostly to cases where the blocks tend to be simple. Mostly.

    It avoids nonsense like this:

     [foo doSomething: ^{
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
      } andSomethingElse: ^{
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
           .... lots of code ... 
       }];
    

提交回复
热议问题