目标-C中的协议范例

时间:2011-08-23 12:47:26

标签: iphone objective-c ios interface xcode4

  

可能重复:
  Real world examples of @optional protocol methods

最近我开始了解目标C.到目前为止,我已经开始编写简单的代码,所有新手都可以了解编程模型的工作原理。然而,当我开始学习协议时,我突然感到困惑。我基本上来自java背景,所以我在想**协议必须与Interface类似。

所以关于协议的问题是,

为什么协议需要可选功能?如下面的代码,

@protocol DuckProtocol
@required
-(void) quack;
@optional
-(void) fly; //Not all ducks can fly
@end

上面的代码没有帮助我理解,拥有协议(java中的接口)的目的是约束程序员,以确保他们在实现此协议的类中实现了所有列出的方法。而不是我们需要@optional的原因?

如果有人曾经使用过这个,你能否分享一下你对这个范例如何帮助你的看法?

由于

8 个答案:

答案 0 :(得分:6)

我对@optional的处理方法是它允许保证(但不必要)定制对象的行为。考虑UITableViewDataSource协议。它有11种方法,但要制作一个功能表,你只需要实现其中的两种。其他9种方法仅用于表格自定义,Apple本身提供合理的默认值。

答案 1 :(得分:5)

协议通常用于为类提供某些功能。但并不总是需要为特定任务定义协议中的所有方法。类在任何地方都不需要“成为”某个协议的方法是可选的。

协议通常用于定义委托。要使类成为另一个类的可能委托(或多或少像回调),它必须响应协议中定义的某些消息(方法调用)。在某些情况下,委托的某些方法永远不会被调用,因为它们不适用于情况和设置。这些方法可以在协议中成为可选的,因此它们不必在委托中实现。如果它们都是必需的,就像在Java中一样,它们可能会被实现为空方法。

我想,动态调用方法的事实使得这更容易。调用委托的类实际上可以在尝试调用委托之前检查是否在委托上实现了方法。

答案 2 :(得分:4)

简单。 Objective-C为我们提供了跳过实现我们不需要的方法的条款。

Java中的Consier KeyListener。如果实现它,则必须实现所有方法 keyPressed(KeyEvent e) keyReleased(KeyEvent e) keyTyped(KeyEvent e),即使你不需要所有这些。

但是,在Objective-C中,您可以指定@optional方法来省略不必要的方法实现。

答案 3 :(得分:3)

//Not all ducks can fly.  

但是,有些人这样做 所以@optional适合那些可以飞行的人实施。

在现实世界中,某些类需要实现一些方法,不需要所有 在Objective C中,协议的实现者可以为程序员提供灵活性,以决定是否使用@optional实现自定义类的方法。

最好的例子是UITableViewDataSource

答案 4 :(得分:2)

如回答Real world examples of @optional protocol methods,可以在特定系列事件之后触发协议中的可选方法。要仍然符合协议并实现它,您只需要所需的方法并增加灵活性。

另请参阅有关协议http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF148

的Apple文档

请注意,它与java接口并不完全相同,因为类可以在不声明实现协议的情况下实现协议。

答案 5 :(得分:2)

协议定义了您的类在执行某些任务时所遵循的方法,通常是其他类实例的委托。

例如,UITableViewDataSource协议定义- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;等方法

第一个是必需的,另一个是可选的。因为表视图需要知道要显示多少行,但它不需要知道有多少部分(它将默认为1部分)。所以第二个方法是在UITableView.h中的@optional下声明的。当您创建一个将充当表视图数据源的类时,将其定义为@interface ClassName : SuperClassName <UITableViewDataSource>,它告诉编译器您的类符合此协议。

如果你没有实现第一个方法,编译器会告诉你你的实现不完整,但如果你没有实现第二个方法,代码将在没有警告的情况下构建和运行。

答案 6 :(得分:2)

Objective-C协议确实类似于Java接口。它们提供了一个抽象级别,可以在使用启用协议的类的任何类中实现多态性。这意味着任何使用您的协议实现的类都可以确保特定方法可用。

可选方法就是他们所说的:可选。任何采用协议的类都可以实现这些方法,但它们并不是必需的。

在实现Delegate设计模式时,协议的使用最有用。每当您为类或回调方法声明委托时,强制委托符合协议可确保所有必需的回调都可用。在UI开发中,这通常可确保您的视图将对更新的数据存储或网络事件做出适当响应。

答案 7 :(得分:2)

我正在编写一个HTTPRequest框架,该框架的协议采用如下方法,需要由使用我的框架上传/下载文件的类实现,

@protocol HTTPRequestDelegate
@required
-(void)HTTPRequestSuccessWithData:(NSDictionary *)inDictionary;
-(void)HTTPRequestFailedWithError:(NSError *)inError;
@optional
-(void)fileUploadPercentage:(NSInteger)inPercent;
@end

现在,使用我的框架上传/下载文件的类必须实现@require方法来获取上传/下载的结果,但只有在需要时它才能实现@optional方法,如果是类的话想要在一些进度指示器中显示上传/下载百分比,它还必须实现fileUploadPercentage:方法。如果班级不打扰已完成的百分比,则无需实施该方法。希望这会有所帮助。