Ios 阻止回调或协议在VIPER中的DataManager和Interactor之间传递信息?

Ios 阻止回调或协议在VIPER中的DataManager和Interactor之间传递信息?,ios,objective-c,architecture,viper-architecture,Ios,Objective C,Architecture,Viper Architecture,当使用Objective-C时,当使用VIPER架构模式时,这是将对象从DataManager传递到interactior的首选方法 特别是使用基于块的回调与数据管理器输出协议 从 像这样使用基于块的回调 -(void)开始日期:(NSDate*)开始日期结束日期:(NSDate*)结束日期完成块:(void(^)(NSArray*todoItems))完成块之间的todoItems 鉴于来自旅工程部 使用DataManager上的OutputProtocol [self.interactior

当使用
Objective-C
时,当使用
VIPER
架构模式时,这是将对象从
DataManager
传递到
interactior
的首选方法

特别是使用
基于块的回调
数据管理器输出协议

像这样使用
基于块的回调

-(void)开始日期:(NSDate*)开始日期结束日期:(NSDate*)结束日期完成块:(void(^)(NSArray*todoItems))完成块之间的todoItems

鉴于来自旅工程部

使用
DataManager上的
OutputProtocol

[self.interactior foundUser:user]

哪种方法更好?为什么


注意:我知道当使用Swift时,闭包可以使回调方法更干净。这个问题与Objective-C直接相关。

这不是简单的问题,而是:

  • 如果只有一个回调,则倾向于使用完成块
  • 如果存在相关回调系列,则倾向于协议/委托
  • 您可能还可以使用其他启发式方法(例如,如果可能有一个明显的对象来实现该协议,并且只需要实现一次,那么委托会更好)


    你可以在苹果的框架中看到这两种方法。在使用块之前,使用target/selector的调用更多——我想说的是永远不要使用它(而是使用块)

    我倾向于在可能的情况下使用输出协议,因为它使测试更容易。当只有一个侦听器时,使用输出协议更容易。如果有多个侦听器,则更容易使用回调块,这样对象就不必跟踪每个请求的接收者

    我发现输出协议更容易测试,因为您可以直接调用侦听器。例如,演示者通常实现交互者的输出协议。假设我们的登录交互输出协议有两种方法:

    -(无效)登录
    -(无效)登录失败错误:(n错误*)错误

    在测试登录演示者时,我们希望编写登录成功和登录失败的测试。登录成功测试可直接调用
    [presenter didLogin]
    和失败测试可以直接调用
    [presenter loginFailedWithError:badCredentialsError]

    相反,如果我们使用了回调块,则登录交互器界面可能类似于:

    -(void)登录,用户名:(NSString*)用户名密码:(NSString*)密码结果:(void(^)(NSError*error))块

    在测试演示者时,要测试成功案例,您需要存根Interactor login方法以返回成功,然后在演示者上调用一个方法,强制其向Interactor发出登录请求

    [交互者将成功];
    [演示者登录]

    这使得您的测试不太清楚实际意图

    如果您可以设计DataManager API来支持输出协议,那么测试就会更容易。如果没有,我就不用担心了,只需使用回调块