我的基于块的API应该刚刚完成还是成功和失败处理程序?

时间:2013-08-21 16:31:23

标签: objective-c api objective-c-blocks

在ObjC中设计基于块的API时,哪种方法更好,一个或两个完成块,一个是成功还是失败?

假设我们有一个方法异步检索一个块,一个完成块就是:

- (void) retrieveSomethingCompletion:(void (^)(id retrievedObject, NSError *error))completionBlock;

使用成功/失败块(AFNetworking样式):

- (void) retrieveSomethingSuccess:(void(^)(id retrievedObject))successBlock failure:(void(^)(NSError *error))failureBlock;

我总是使用第二种方法,但每种方案的优缺点是什么?你通常使用什么,为什么?

3 个答案:

答案 0 :(得分:12)

两者都是很好的模式(我赞成Firo和John的答案,因为 - 是的,这是一个品味问题,他们的答案都是现场的),但是单个街区有几个明显的优点, 在我的经验中。 John Woods对API的“风味”提出了一个很好的观点,尽管我声称网络操作总是完成(除非它没有超时,这是一个不同类的bug)并且成功/失败模式并不完全是/或。

  • 无论成功与否,它都不需要在完成时拆除任务的常用块之间复制代码。

  • 它在调度任务和知道任务何时完成之间提供单个概念执行流程。 完成此任务后,将调用完成块。

  • 在某些情况下,失败实际上可能会产生应以成功路径等方式处理的数据。在较少的情况下,成功完成实际上可能会带来错误。虽然方法上的NSError**模式纯粹是/或,但使用任一块模式的优点之一是可以表达。使用单个完成块的另一个好处是可以避免重复逻辑。

  • 多个块作为方法的参数很难看,也很烦人。编码模式仅将一个块传递给方法并始终使该块成为最后一个参数的原因是有原因的。不幸的是,即使系统API也不能始终如一地遵循这种模式,尽管对于块往往简单的情况,主要的使用受到限制。居多。

它避免了这样的废话:

 [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 ... 
   }];

答案 1 :(得分:7)

我通常使用第二种实现方式。原因如下:

  1. 它更适合重复使用块。我经常对失败有相同的实现,所以我可以创建一个返回失败块的方法,并根据需要更改成功块。您可以使用第一个实现执行此操作,但是您需要嵌套块。

  2. 我喜欢在可能的情况下避免不必要的检查(“如果错误然后对我的错误执行某些操作,否则对我的对象执行某些操作”)。由于我要么得到一个对象或一个错误(从来没有),我发现当只有一个参数有效时,传递这两个参数是不方便的。

  3. 我使用Restkit,我只需要将块传递给我的API调用,当调用进来时它会自动调用成功或失败块。如果我执行第二个实现,我需要处理方法回调(失败或成功方法/块)并手动执行块。我不确定AFNetworking。

  4. 我个人认为两者都很好,但在这种情况下我会争论第二个。

答案 2 :(得分:3)

在我看来,这是非常主观的。考虑API的用例场景,用户可以从完成或成功/失败中获益更多吗?

如果它像网络访问API那样AFAetworking可能会成功/失败 - 它更合适。但是,如果API每次都可能成功完成,即动画块,那么最好完成