Objective C协议的使用

我有一个作业问题困扰着我,真的很糟糕。 以下是一个问题的简要解释。

想象一下,你正在开发一个存储联系人信息的应用程序。 地址簿可以包含许多实体types,例如人类,公司或其他任何具有联系信息的实体types。

  • 现在,而不是显式检查每个对象types写一个协议,声明一个对象必须如何行为,并成功地出现在您的地址簿。

我回答这个问题的理解和努力是,

  1. @required标签下build立一个具有每种联系信息types常用方法的协议。 和其他所有不同的联系方式(如传真号码与公司有关系,但不是人员…)在@optional。 在运行时,您可以使用selector检查对象是否响应任何给定的方法。 怀疑:然而,这又是间接地明确检查对象types,对吗?

  2. 我的第二个想法是在java中使用类似abstract class东西。 这意味着从抽象类inheritance的类实现了自己的抽象方法。 作为一个天真的iOS开发人员,我不知道如何实现这个? 我不确定这是否会解决我的问题。 如果有人知道这一点,我想得到启发。


外部阅读到目前为止,请让我知道如果我正在寻找的答案是在这些链接之一。 我会再读一遍理解和解决这个:)。 谢谢。

  1. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF144

  2. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF146

  3. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF149

协议和Java接口是一样的。 它只是定义了类应该支持哪些方法。 这是一个清楚地解释它的页面: http : //www.otierney.net/objective-c.html#protocols

本质上,如果你想确保一个类将有一个phoneNumber方法( phoneNumber属性的访问者),你会做这样的事情:

 @protocol ContactProtocol -(void) phoneNumber; @end @interface Person: NSObject <ContactProtocol> { ... } @interface Company: NSObject <ContactProtocol> { ... } 

然后在编译时(或为xcode 4生活)它会告诉你,如果你忘记将phoneNumber方法添加到PersonCompany类。

但是,这又是间接地显式检查对象types,对吗?

不,检查行为与检查types不同。 您可以将-respondsToSelector:发送给任何对象,如果结果为YES,则无论对象的types如何,都可以发送消息。 你也可以要求一个对象实现一个给定的协议,而不用关心它的实际types:

 id<SomeProtocol> foo; // foo points to any type that implements SomeProtocol 

我的第二个想法是在java中使用类似抽象类的东西。

这可以工作,但显然不是你的任务要求,对不对? 它说“…写一个协议…”

Objective-C没有提供一种按照Java的方式显式创build类抽象的方法。 你只需要创build这个类,如果你不想直接实例化它,那么你可以在某个地方进行文档化。

你有…选项。

可选方法便于写作课程的人员符合协议,对使用该协议的人感到烦恼。 所以这取决于你想要取悦谁。

可选的方法并不像检查types那么糟糕。 设想一下访问可接触实体对象时代码的外观。 当你使用可选方法时,你必须有一个if case和一个else case。 这不像前进方便,并假设你可以调用的方法。 但是比检查types更方便。 对于每种不同types的实体(以及其他情况,这可能是断言),这将是一种情况。 此外,如果使用可选方法,则有关实体的信息将封装在其类中。 如果在调用方法之前检查types,那么实体提供的有关联系信息types的信息在调用代码的类外部。 如果您升级实体以提供其他types的联系人,那么在您更新调用代码之前,这种改进不可用。

选项B是使所有需要的方法,但给他们的选项返回一个值,指示没有信息,如无。 当然,这仍然意味着如果检查一个零结果,它只是不太详细。 这个问题的更好的解决scheme是让方法返回多个联系人的集合。 毕竟,人们可以有多个电话号码。 然后,为了表明联系人types不适用,您只需返回一个空集合。

不利的一面是,写符合协议的类的人不得不添加一个简单的存根方法来表示return nil或其他东西。