Objective-c异步通信:目标/动作或委托模式?

时间:2009-12-22 17:15:52

标签: iphone objective-c cocoa target delegation

我正在处理一些异步通信情况(事件驱动的XML解析,NSURLConnection响应处理等)。我将尝试简要解释一下我的问题:

在我目前的场景中,有一个服务提供者(可以与xml解析器通信或进行一些网络通信)和一个可以要求服务提供者异步执行某些任务的客户端。在这种情况下,当服务提供者完成其处理时,它必须将结果传回给客户端。

我正试图找到一种模式或经验法则来实现这类事情,我看到了3种可能的解决方案:

1。使用委托模式:客户端是服务提供者的委托,它将在任务完成时收到结果。

2。使用目标/操作方法:客户端要求服务提供者执行任务并传递一个选择器,该选择器在完成任务后必须由服务提供者调用。

第3。使用通知

更新)经过一段时间尝试解决方案#2(目标和行动)后,我得出的结论是,在我的情况下,最好使用委托方法(#1) 。以下是每个选项的优缺点,正如我看到的那样:

授权方法:

  • 1(+)选项1的优点是我们可以检查编译时错误,因为客户端必须实现服务提供商的委托协议。

  • 1( - )这也是一个缺点,因为它导致客户端与服务提供商紧密耦合,因为它必须实现其委托协议。

    < / LI>
  • 1(+)它允许程序员轻松浏览代码并找到客户端的哪种方法,服务提供商正在调用以传递其结果。

  • 1( - )从客户端的角度来看,一旦获得结果,就很难找到服务提供商调用的方法。它仍然很简单,只需转到委托协议方法,就是这样,但#2方法更直接。

  • 1( - )我们必须编写更多代码:定义委托协议并实施它。

  • 1( - )此外,应该使用委托模式来委派行为。从语义上讲,这种情况不一定是授权的确切情况。

行动/目标方法

  • 2(+)选项2的优点是,当调用服务提供者方法时,还必须指定指定回调操作的@selector,因此程序员知道正确将调用哪个方法来处理结果。

  • 2( - )与此相反,在浏览服务提供商代码时,很难找到在客户端中回调哪种方法。程序员必须进入服务调用,看看传递了哪个@selector。

  • 2(+)这是一个更具动态性的解决方案,会减少部件之间的耦合。

  • 2( - )也许最重要的事情之一:它可能导致运行时错误和副作用,因为客户端可以传递一个选择器服务提供商不存在。

  • 2( - )使用简单的标准方法(#performSelector:withArgument:withArgument :),服务提供者最多只能传递2个参数。

通知:

  • 我不会选择通知,因为我认为在需要更新多个对象时应该使用它们。此外,在这种情况下,我想直接告诉委托/目标对象在构建结果后要做什么。

结论:此时,我会选择委托机制。这种方法提供了更高的安全性,并允许轻松浏览代码以跟踪向委托发送服务提供者操作结果的后果。关于这个解决方案的负面影响是:它是一个更静态的解决方案,我们需要编写更多的代码(协议相关的东西),从语义上讲,我们不是真正谈论委托,因为服务提供商不会委托任何东西

我错过了什么吗?你推荐什么,为什么?

谢谢!

3 个答案:

答案 0 :(得分:3)

你确实错过了第三个选项 - 通知。

您可以让客户端观察来自服务提供商的通知,表明它有新数据可用。当客户端收到此通知时,它可以使用服务提供商提供的数据。

这允许良好的松散耦合;一些决定只取决于您是否需要推/拉系统。

答案 1 :(得分:0)

非常好的问题。

我不认为我是合格的,只是(因为我是新手),评论哪种设计模式比另一种好。但只是想提一下,你可以通过

来避免你在第2点(运行时异常)中提到的缺点
if([delegate respondsToSelector:callback]){
    //call to callback here
}

希望有助于衡量选项

答案 2 :(得分:0)

该代表团方法的另一个缺点: 服务提供商只能拥有一个委托。如果您的服务提供商是单身,并且您有多个客户端,则此模式不起作用。

这导致我采取行动/目标方法。我的服务提供商持有州,并在多个客户之间共享。