4

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

例如:

    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 设置委托变量在某种程度上等于将父实例赋予子实例并让子实例在需要时调用该函数,协议在这里有什么帮助或者我们为什么需要协议?有什么好处?

谢谢

4

3 回答 3

2

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

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

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

于 2013-08-21T05:02:08.957 回答
2

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

假设您正在编写一个通用应用程序。您的代码中有两个视图控制器,iPadViewController它们iPhoneViewController都需要从 Web 服务中获取数据。因此,您为 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 控制器都可以成为委托,并且通过符合协议,他们“承诺”他们将实现所需方法的 Web 服务类- (void)webServiceDidGetArray:(NSArray *)array;

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

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

于 2013-08-21T12:30:56.223 回答
0

委托调用与普通方法调用没有区别!

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

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

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

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

于 2013-08-21T12:27:34.483 回答