2015-02-05 40 views
0

我真的很希望有人能回答这个问题。我认为我绝对不是唯一一个对此感到困惑的人,我无法找到任何清楚解释这个概念的东西。红宝石代表从可可开发人员背景解释

我对委托模式的理解来自于研究Cocoa框架。对我来说,可可的实施非常明确。但是我很难在Ruby中理解它(标准库的Delegator,SimpleDelegatorActiveSupportDelegate)。这对我来说毫无意义。主要是因为一个是类型安全的,另一个是鸭子类型。你已经可以看到我的观点,但请允许我扩大......这里是我的如何使用可可的委托模式总结:

我们的“成分”是:2类,AB和,这Cocoa是可用于委托的预定义方法集。

的模式的实现,基本上如下:

  1. A定义了一套方法委托给B
  2. B的委托被设置为A

    =>B现在可以调用委托方法,像这样:@delegate.send(a_delegated_method)

什么我不绑在一起的是红宝石采用鸭打字的事实,所以你可以发送任何方法调用任何对象,对吧?因此,使用我刚刚解释的模式,只要2个对象处于同一个域中,您可以在A@b.send(:a_delegated_method)之间说,反之亦然,而在B@a.send(:another_delegated_method)

难道是在Ruby中委托的地方是委托方法被定义的地方吗?意思是我们从A类别内发送到属性@b@b(:delegated_method))a :delegated_methodA本身内定义的内容?

希望这不是太混乱。我自己很疑惑,为什么代表甚至存在鸭子打字的语言,以及Delegator,SimpleDelegatorActiveSupportDelegate之间有什么区别。

+0

委托是_pattern_。它与打字工作无关。这两件事不仅是正交的,它们完全没有关系。 – matt 2015-02-05 19:33:10

+0

我知道这是一种模式,但我的问题更多地是关于在两种不同的环境中实施模式的变化,如果这是有道理的。 – believesInSanta 2015-02-05 20:10:39

回答

1

我不清楚你是否了解代表团如何在可可中工作。的确,Cocoa中委托模式的常见变种涉及到一个协议,但这只是一种静默编译器的方式。

所以我们先来谈谈静音编译器。你不能发送woohoo消息对象在Objective-C,除非两种情况之一是真实的:

  • 编译器有理由相信,这种对象可能为woohoo消息作出响应。

  • 编译器暂停判断。

现在,第一种方法通常被使用 - 这就是协议的用途。但情况并非总是如此。它曾经是该代表团主要依靠非正式协议。可可还有非正式的协议。这个想法是要么这个方法是通过一个类别注入到NSObject中的,要么你注意键入对象作为id,这样它就可以发送任何消息。

现在让我们来谈谈动态。非正式协议不再使用的原因是引入了允许协议声明可选成员的功能。但是仍然需要活力!我们可能会以某种方式满足编译器,但在运行时我们必须确保将特定消息发送到某个对象是安全的。您的应用程序代理可能会采用UIApplicationDelegate,但Cocoa不会将它发送给applicationDidBecomeActive:消息,除非您的应用程序代理类实现了applicationDidBecomeActive: - 如果确实如此,则会崩溃,而且这不会很好。

而且,如果你可以让过去的编译器,你可以在Objective-C甚至比这更动态地进行授权,如下解释:

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html

的想法是,我们正前方去在运行时并且无论如何都会向对象发送消息!如果消息到达对象A无法处理,它可以看到对象B是否处理它。如果是这样,它将消息传递给对象B.因此,我们可能不会崩溃!我用这种方法在我的应用程序之一:

- (id)forwardingTargetForSelector:(SEL)aSelector { 
    if ([self.originalDataSource respondsToSelector: aSelector]) 
     return self.originalDataSource; 
    return [super forwardingTargetForSelector:aSelector]; 
} 

在该代码中,我的意思是,如果有消息到达,我不能处理它,我应该尝试把它发送到另一个对象,称为self.originalDataSource

如果您仔细考虑,那几乎与Ruby代表团完全相同。我有一个帮助对象,并且我无法处理的消息被传递给它。

此模式的另一种常见用法是包装可可集合时。你不能继承子类,比如NSArray,因为它是一个类集群,所以正确的方法就是包装它。然后,您只需将所有内容转发给NSArray,然后将其作为NSArray进行鸭式输入!就你的方法而言,你看起来像一个NSArray。然后你介绍一些行为上的差异,现在你将鸭子作为定制的NSArray。

+0

当你提到Ruby代表团时,你指的是Rails的ActiveSupport#委托吗?标准图书馆的委托人呢?为什么即使有这些消息发送?你是说它只是处理method_missing异常呢?我意识到4个问题重叠有点btw :) – believesInSanta 2015-02-05 20:07:16