【问题标题】:How does delegate call differ from normal method call ?委托调用与普通方法调用有何不同?
【发布时间】:2026-01-30 07:50:01
【问题描述】:

每当我想向父类通知某些内容时,我都会使用委托而不是直接调用父类的函数。我是这样实现的……

例如:

    CustomClass *custom = [[CustomClass alloc] init];
    // assign delegate
    custom.delegate = self; // Here we are giving parent instance like normal method call.
    [custom helloDelegate];

在自定义类中,我已经像下面这样暗示了父母......

-(void)helloDelegate
{
    // send message the message to the delegate
    [_delegate sayHello:self];
}

所以我的疑问,它与直接调用有何不同?使用 self 设置委托变量在某种程度上等于将父实例赋予子实例并让子实例在需要时调用该函数,协议在这里有什么帮助或者我们为什么需要协议?有什么优势?

感谢

【问题讨论】:

  • 促进松耦合
  • 如果你从不改变你的代表,那是一样的,如果你的代表可以不止一件事,那就不同了。
  • “通知父类”是什么意思?如果您在派生类中,那么派生类本身就是父类的一个版本。虽然如果你想向父类通知一些东西,请使用 [super methodName:]。
  • @zneak 你能提供更多关于它的信息吗?
  • @CodenameLambda1 它不是派生的.. 自定义类是从父类加载的...

标签: ios objective-c methods delegates protocols


【解决方案1】:

一个使用委托而不是使用直接关系的优势的工作示例。

假设您正在编写一个通用应用程序。您的代码中有两个视图控制器iPadViewControlleriPhoneViewController,它们都需要从Web 服务获取数据。所以你为你的网络服务调用webServiceDownloaderClass创建一个类。

现在,您的两个视图控制器都需要在 webServiceDownloaderClass 完成时得到通知。

您的选择在这里...

方案一强耦合

在你iPadViewController 中你定义了一个方法- (void)webServiceDidGetArray:(NSArray *)array;。在iPhoneViewController 中定义相同的方法。

为了让webServiceDownloaderClass 调用这些方法,它现在需要对每个控制器的引用...

@property (nonatomic, strong) IPadViewController *iPadController;
@property (nonatomic, strong) IPhoneViewController *iPhoneController;

然后当它完成时,它需要确定调用哪一个......

if (iPadController) {
    [iPadController webServiceDidGetArray];
}

etc....

这里的缺点是视图控制器在某种程度上定义了 Web 服务类在完成时会做什么。此外,如果您添加另一个控制器,您将拥有另一个属性,并且无法保证您引用的控制器实际上具有您尝试调用的方法。

选项 2 委派

在您的我们服务类中,您定义一个协议。

@protocol WebServiceDownloaderDelegate <NSObject>

- (void)webServiceDidGetArray:(NSArray *)array

@end

还有一个代表...

@property (nonatomic, weak) id <WebServiceDownloaderDelegate> delegate;

现在您正在 Web 服务类中定义 Web 服务类的操作。而且您只需要对任何想要成为委托的类的引用。此外,任何类都可以是委托。因此,现在 iPad 和 iPhone 控制器都可以成为委托,并且通过遵守协议,他们“承诺”他们将实现所需方法 - (void)webServiceDidGetArray:(NSArray *)array; 的 Web 服务类。

当然,这只是委托有用的一种情况。

在某些情况下,您可能应该使用直接关系而不是委托。

【讨论】:

    【解决方案2】:

    委托调用与普通方法调用没有不同!

    不同的是事物的使用方式,这与调用机制无关。委托用于将提供委托服务的代码的定义与“使用”委托服务的代码分离,因此“消费者”(奇怪的是,通常是代表委托提供者的服务)不必被编码以了解那个特定的委托提供者。

    在 Objective C 中,委托通常使用“协议”来实现,但这远不是协议的唯一用途。 Objective C 广泛使用它们来提供各种 Cocoa 类之间的通用接口。

    而且,在有限的情况下,可以合法地使用通用超类而不是协议来实现委托。

    如果您有两个属于同一开发工作的类,并且它们不可能彼此分开使用,则无需使用委托“模式”来促进它们之间的通信,即使它们是服务消费者/服务提供者的关系。这样做的唯一原因是“按规范”,以防“服务”在不同的项目中被原封不动地重用。

    【讨论】:

      【解决方案3】:

      您的问题实际上是关于子类化而不是实现协议(或其他语言如 java 的接口)之间的区别..

      使用委托,您正在实现一个协议..(这是引用委托的类与委托本身之间的合同)..这比子类化为您提供了更大的灵活性,因为通过子类化您将自动继承超类(这比简单地使用另一个类的某些方法更具限制性。换句话说:子类化 = 是一种 关系.. 而实现协议(与委托相同)= 有一个关系。

      如果你读过任何关于设计模式的书。他们会广泛讨论松耦合代码和编写防止修改但允许扩展等的优点。基本上使用委托而不是子类化是实现这些设计最佳实践的一种方式。

      【讨论】: