2011-10-01 71 views
15

我有一个家庭作业问题让我很困惑。以下是一个问题的简要解释。Objective C协议的使用

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

  • 现在不是明确地检查每一个对象类型写 协议,声明了一个对象必须的行为,并成功 出现在您的地址簿。

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

  1. 构建具有下@required标签每种类型的联系人信息的常用方法的协议。和其他所有不同的联系方式(如传真号码与公司有关联,但不包括人员...)在@optional之下。在运行时,您可以使用selector来检查对象是否响应任何给定的方法。 疑问:但是,这又是间接显式检查对象类型,我是对吗?

  2. 我的第二个想法是在java中使用类似abstract class的东西。这意味着从抽象类继承的类实现了自己的抽象方法。作为一个天真的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

+5

问题作业问题的绝佳方式。 +1以下http://catb.org/esr/faqs/smart-questions.html – 0x8badf00d

+0

此链接清楚解释协议概念http://www.tutorialspoint.com/ios/ios_delegates.htm –

回答

10

协议是相同的东西作为一个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类。

+6

协议不一样抽象类;它们与Java中的接口类似。当你从一个抽象类派生一个类时,你继承了这两个方法及其实现。通过一个接口,你只能得到声明。 Obj-c协议也是如此 - 当你声明一个类实现了一个协议时,你必须提供方法实现。 – Caleb

+0

你是对的。我正在考虑接口!我正在更新我的答案。 –

+0

到Otierney.net的链接目前停用。这里有一个链接到谷歌的缓存,不知道它会工作多久。http://webcache.googleusercontent.com/search?q=cache:QbGm74kZa1wJ:www.otierney.net/objective-c.html+&cd=1&hl=zh-CN&ct=clnk&gl=us – kevins

4

但是,这又是间接显式检查对象类型,对吗?

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

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

我的第二个想法是使用类似Java中抽象类。

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

Objective-C没有提供一种方法来明确地做出一个Java抽象类的抽象方法。你只需创建这个类,如果你不希望它直接实例化,那么你可以在某个地方记录它。

+0

此问题与Swift无关,但如果那么,如果我错了,请纠正我的错误:你的第一个答案是:是的,现在在Swift中,协议是一种类型,只是你委托?.someMethod而不是与respondsToSelector相同它将运行函数如果设置了委托......第二个问题:(在阅读你接受的答案的评论之后)在Swift中,因为你也可以像抽象类一样为协议提供默认实现。 – Honey

+1

@Honey这个答案早于Swift,应该在这种情况下阅读。我的评论也一样。即使问题与Swift同时出现,问题的标题清楚地表示为“Objective-C”,问题被标记为[tag:objective-c]。 – Caleb

+0

我真的知道这一点,我只是问起它与Swift的区别,这个主题有答案,我只是检查是否能够正确地将所有内容放在一起(尤其是与上面的注释一起)。 – Honey

1

你有...选项。

可选的方法对于编写类符合协议的人来说是很方便的,对于使用协议的人来说很烦。所以这取决于你想要取悦谁。

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

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

不足之处在于,谁写符合协议的类的人必须添加一个简单的存根方法,说return nil什么的。