2011-03-25 58 views

回答

74

使用Objective-C中的(@protocol语法)声明的协议用于声明类“采用”(声明它将使用此协议)将实现的一组方法。这意味着你可以在你的代码中指定“只要它实现了一个特定的协议,你不关心使用哪个类”。这可以在Objective-C进行如下:

id<MyProtocol> instanceOfClassThatImplementsMyProtocol;

如果你在你的代码说明这一点,那么任何类,“符合”的协议MyProtocol可以在可变instanceOfClassThatImplementsMyProtocol使用。这意味着使用这个变量的代码知道它可以使用这个方法在MyProtocol中定义的这个特定的变量,而不管它是什么类。这是避免继承设计模式的好方法,并且避免了紧耦合。

代表是使用协议的语言功能。 delegation design pattern是一种设计您的代码以在必要时使用协议的方式。在Cocoa框架中,委托设计模式用于指定符合特定协议的类的实例。这个特定的协议指定了委托类应该实现的方法,以便在给定的事件中执行特定的操作。使用委托的类知道它的委托协议,所以它知道它可以在给定的时间调用实现的方法。这种设计模式是解耦类的一种很好的方式,因为它使得交换一个委托实例变得非常容易 - 程序员必须做的是确保替换实例或类符合必要的协议(即它实现了协议中指定的方法)!

协议和委托并不仅限于Objective-C和Mac/iOS开发,但Objective-C语言和Apple框架大量使用了这种令人敬畏的语言功能和设计模式。

编辑:

下面是一个例子。在Cocoa Touch的UIKit框架中,有一个UITextFieldDelegate协议。这个协议定义了一系列的方法,这些方法是实例应该实现的一个UITextField的代表。换句话说,如果您想要将代理指定给UITextField(使用delegate属性),最好确保此类符合UITextFieldDelegate。事实上,由于的UITextField委托属性定义为:

@property(nonatomic, weak) id<UITextFieldDelegate> delegate

编译器会,如果你指定一个类,它没有实现该协议给予警告。这非常有用。你必须声明一个类实现了一个协议,并且在说明它的时候,你让其他类知道他们可以以特定的方式与你的类进行交互。所以,如果你指定的实例MyTextFieldDelegateClassdelegate财产的UITextField,在的UITextField知道,它可以调用一些特定的方法(与文本输入,选择等)你MyTextFieldDelegateClass的。它知道这是因为MyTextFieldDelegateClass已经表示它将实现UITextFieldDelegate协议。

最终,这一切都会在您的项目代码中产生更大的灵活性和适应性,我相信您在使用此技术后很快就会意识到这一点! :)

+3

所以协议为你做什么,委托方式去做吧? – 3lvis 2012-09-06 06:14:30

+13

我不确定我是否跟着你。委托是一种设计模式,它允许一个类以一种解耦代码的方式承担另一个责任(非常好,灵活的事情)。协议是一种Objective-C语言功能,允许您编写和使用使用委托概念的代码。 – 2012-09-06 10:40:41

+0

@JamesBedford你能告诉我“id 是什么意思” – Exploring 2013-08-13 06:59:12

13

团:代理上另一个对象的代(设计在糟糕图案)

它是一个设计图案在其中一个对象被称为委托的行动代表的,并在该请求,另一个对象。在执行过程中,它向它的代理发送一条消息;该消息告诉委托人某些事件即将发生并请求一些响应。代理实现由消息调用的方法并返回适当的值

一个示例是appdelegate对象代表appobject行事。

协议:启用对象通过继承

的协议不相关之间的通信是一个编程接口,其方法中的任何类可以implement.Protocols是目标C语言特征 .Simply发言的列表的声明任何类都可以实现的方法。要使用它,您需要确认协议。 示例是UITableviewDatasource协议,其方法cellforRowAtIndexPath在协议中声明,但我们实现它以创建tableview。

参见https://developer.apple.com/library/mac/referencelibrary/GettingStarted/RoadMapOSX/books/StreamlineYourAppswithDesignPatterns/StreamlineYourApps/StreamlineYourApps.html

12

协议是一组方法(无论是可选的或必需)的那些将被符合该协议的类来实现。而委托则是指那个符合该协议的类,并且将遵守协议中定义的实现方法。

查看this了解更多详情。

+1

我见过的最好的解释,谢谢。 – 2017-08-28 18:40:03

+0

请注意在这种情况下的答案.. – NSPratik 2017-08-28 18:50:50

+1

别担心,我做到了。 – 2017-08-28 20:14:24

4

让看到委托的声明在程序

id<myProtocol> *delegatingObject; 

的delegatingObject保持对其他对象并在适当的时间的参考将消息发送到该对象。

协议是一组可以由任何类实现的相关属性和方法。它暗示确认myProtocol(相关属性和方法组)的任何对象(id类型)都可以作为委托来工作,或者你可以说任何具有所需学位(协议)的人(id)都可以作为一个工作组来使用教师(代表)。

4

一种 mportant p rerequisite是理解协议˚F IRST 然后代表。我建议你先看看this简短教程,然后看What is a Protocol?。此外,您必须知道类别和协议之间的区别,请参阅Objective-C: Class versus ProtocolWhat is the point of Protocols?


protocol:只是一个函数来实现的蓝图。任何采用该蓝图的课程都必须实施这些功能。 (请不要误会实现一个函数调用一个功能)

delegate:是你也什么delegat- 荷兰国际集团类是做继承例如

例如,您有一个viewController并想要下载图像或想要获得客户与商店的距离,所以您不需要自己完成所有工作,而只需要一个中型对象,即可为您完成此操作。该对象被称为委托对象。通常你会做一些这样:

class ViewController : UIViewController , DownloaderDelegate{ 
//other code 

(inside viewDidLoad or elsewhere) you write: 
downloaderHandler.delegate = self // now self can also do WHATEVER the delegate can do...previously it was only a viewController but now it's 'almost' also a downloader 

非常相似,你符合一个tableViewDelegate

class ViewController : UIViewController , UITableViewDelegate{ 
//other code 
(inside viewDidLoad or elsewhere) you write 
tableView.delegate = self 

self现在还可以做的tableView相关的东西做什么。


delegate: 但是该对象(委托)是一个普通的对象(ID或任何)。这是愚蠢的!你必须说:“嘿,你需要具备特定的功能,以符合我们为你定义的协议(我们不会扩展任何或id,因为它会变得愚蠢,(取而代之)我们制作一个非常明确的限制协议“在Objective-C
这是一个纯粹的香草id,所以你做

@property (weak) id<DownloaderProtocol>delegate; 

斯威夫特*这是稍微容易一些,你这样做:

weak var delegate:DownloaderProtocol? 

协议来救援......的德legate实现(不使用)功能,但它适合您的委派类的需要。


*:在斯威夫特你没有id还是你不需要它的等效Any因为斯威夫特协议也是一等公民类型