gpt4 book ai didi

ruby - 从 Cocoa 开发者背景解释 ruby​​ 中的委托(delegate)

转载 作者:行者123 更新时间:2023-12-03 17:50:40 26 4
gpt4 key购买 nike

我真的希望有人能回答这个问题。我想我绝对不是唯一对此感到困惑的人,而且我找不到任何可以清楚解释这个概念的东西。

我对委托(delegate)模式的理解来自于对Cocoa框架的研究。对我来说,Cocoa 的实现非常清晰。但我很难在 Ruby 中理解它(标准库的 DelegatorSimpleDelegatorActiveSupportDelegate)。这对我来说没什么意义。主要是因为一个是类型安全的,另一个是鸭子类型。您已经明白我的观点了,但请允许我扩展一下...以下是我对如何在 Cocoa 中使用委托(delegate)模式的总结:

我们的“成分”是:2个类,AB以及一个协议(protocol),这是Cocoa的一组预定义的用于委托(delegate)的方法。

该模式的实现基本如下:

  1. A 定义委托(delegate)给 B 的一组方法。

  2. B 的委托(delegate)设置为 A

    => B 现在可以调用委托(delegate)方法,如下所示:@delegate.send(a_delegate_method)

我没有将 Ruby 使用鸭子类型这一事实联系在一起,因此您可以向任何对象发送任何方法调用,对吧?因此,使用我刚刚解释的模式,只要两个对象位于同一域中,您就可以说 while in A @b.send(:a_deleerated_method) ,反之亦然在 B @a.send(:another_deleerated_method) 中。

Ruby 中的委托(delegate)的重点是不是定义委托(delegate)方法的地方?这意味着我们从类 A 内部向属性 @b (@b(:deleerated_method)) 发送一个 :deleerated_methodA 本身中定义?

希望这不会太令人困惑。我自己很困惑为什么委托(delegate)甚至存在于鸭子类型语言中,以及 DelegatorSimpleDelegatorActiveSupport 之间有什么区别>委托(delegate)

最佳答案

我不清楚您是否了解委托(delegate)在 Cocoa 中的工作原理。确实,Cocoa 中常见的委托(delegate)模式涉及协议(protocol),但这只是让编译器安静下来的一种方式。

所以让我们首先谈谈让编译器安静下来。您无法发送woohoo向 Objective-C 中的对象发送消息,除非满足以下两个条件之一:

  • 编译器有理由相信该对象可能响应 woohoo消息。

  • 编译器暂停判断。

现在,通常使用第一种方法 - 这就是协议(protocol)的用途。但情况并非总是如此。过去,授权主要依赖于非正式协议(protocol)。 Cocoa 中仍然存在非正式协议(protocol)。这个想法是要么将该方法通过类别注入(inject)到 NSObject 中,要么小心地将对象键入为 id这样就可以发送任何消息。

现在我们来谈谈活力。不再使用非正式协议(protocol)的原因是引入了一项功能,允许协议(protocol)声明可选成员。但仍然需要活力!我们可能会以某种方式满足编译器的要求,但在运行时我们必须确保向特定对象发送特定消息是安全的。您的应用程序委托(delegate)可能会采用 UIApplicationDelegate,但 Cocoa 不会向其发送 applicationDidBecomeActive:除非您的应用程序委托(delegate)类实现 applicationDidBecomeActive: - 如果是这样,你就会崩溃,那就不太好了。

此外,如果您可以通过编译器,则可以在 Objective-C 中更加动态地执行委托(delegate),如下所述:

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 委托(delegate)几乎相同。我有一个辅助对象,我无法处理的消息会传递给它。

此模式的另一个常见用途是包装 Cocoa 集合。你不能子类化 NSArray,因为它是一个类簇,所以正确的方法是包装它。然后,您只需将所有内容转发到 NSArray,然后您就被鸭子类型化为 NSArray!就你的方法而言,你看起来像一个 NSArray。然后你引入一些行为上的差异,现在你被鸭子类型化为自定义的 NSArray。

关于ruby - 从 Cocoa 开发者背景解释 ruby​​ 中的委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28350393/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com