Objective C 协议的使用

发布于 2024-12-07 15:34:09 字数 1801 浏览 0 评论 0 原文

我有一个家庭作业问题让我非常困惑。下面简单解释一下一个问题。

假设您正在开发一个存储联系人的应用程序 信息。地址簿可能包含许多实体类型,例如人类 是、公司或任何其他有联系信息的东西。

  • 现在不用显式检查每个对象类型,而是编写一个 声明对象必须如何成功运行的协议 出现在您的地址簿中。

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

  1. 构建一个协议,该协议在@required标签下具有每种类型的联系信息的通用方法。以及@可选下的所有其他在不同联系人中不相似的方法(例如传真号码与公司相关但与个人无关......)。在运行时,您可以使用选择器检查对象是否响应任何给定方法。 疑问:但是,这又是间接显式检查对象类型,对吗?

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


到目前为止已完成外部阅读,请告诉我我正在寻找的答案是否在这些链接之一中。我会再次阅读它以理解并解决这个问题:)。谢谢。

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

  2. <一个href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF146" rel="noreferrer">http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF146

  3. <一个href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF149" rel="noreferrer">http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF149

I have a homework question which confused me, really badly. Below is a brief explanation of a question.

Imagine you are developing an application that stores contact
information. The address book may contain many entity types e.g. Human
being, a company or anything else that has a contact information.

  • Now instead of explicitly checking every object type write a
    protocol that declares how an object must behave and successfully
    appear in your address book.

My understanding and efforts of answering this question is,

  1. Build a protocol which has common methods of each type of contact information under @required tag. And all other methods which are not similar in different contact(Such as fax number has association with company but not person...) under @optional. At runtime you can check whether an object responds to any given method by using selector.
    Doubt : However this is again explicitly checking object type indirectly, am I right?

  2. My second thought is to use something like abstract class in java. Which means inherited class's from abstract class implements their own abstract methods. How ever as a naive iOS developer I don't know how to implement this? and I am not sure whether this is going to solve my problem. I would like get enlighten if someone knows this.


External Reading done so far, Please let me know if the answer I am looking for is in one of these links. I will read it again to understand and solve this :). thanks.

  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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

明月夜 2024-12-14 15:34:09

协议与 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 类。

A protocol is the same thing as a Java interface. It just defines which methods the class should support. Here's a page that explains it clearly: http://www.otierney.net/objective-c.html#protocols

Essentially if you want to make sure a class will have a phoneNumber method (accessor to the phoneNumber property) you would do something like this:

@protocol ContactProtocol
-(void) phoneNumber;
@end

@interface Person: NSObject <ContactProtocol> {
    ...
}

@interface Company: NSObject <ContactProtocol> {
    ...
}

And then at compile time (or live for xcode 4) it will tell you if you forgot to add the phoneNumber method to the Person or Company classes.

蹲在坟头点根烟 2024-12-14 15:34:09

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

不,检查行为与检查类型不同。您可以将 -respondsToSelector: 发送到任何对象,如果结果为 YES,则无论对象的类型如何,您都可以发送消息。您还可以要求对象实现给定的协议,同样无需关心其实际类型:

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

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

这可能行得通,但这显然不是你的作业所要求的,对吧?它说“...编写一个协议...”

Objective-C 没有提供一种方法来像 Java 那样显式地使类抽象。您只需创建该类,如果您不希望直接实例化它,则可以在某处记录该类。

However this is again explicitly checking object type indirectly, am I right?

No, checking behavior is different from checking type. You can send -respondsToSelector: to any object, and if the result is YES you can send the message regardless of the object's type. You can also require that an object implement a given protocol, again without caring about its actual type:

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

My second thought is to use something like abstract class in java.

That could work, but it's apparently not what your assignment asked for, right? It says "...write a protocol..."

Objective-C doesn't provide a way to explicitly make a class abstract the way Java does. You just create the class, and if you don't want it to be instantiated directly you document that somewhere.

你是暖光i 2024-12-14 15:34:09

你有……选择。

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

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

选项 B 是使所有方法都成为必需的,但给它们提供返回一个指示没有可用信息的值的选项,例如 nil。当然,这仍然意味着用 if 情况来检查 nil 结果,只是不那么冗长。解决此问题的一个更好的解决方案是让这些方法返回多个联系人的集合。毕竟,人们可以拥有多个电话号码。然后,为了指示联系人类型不适用,您只需返回一个空集合。

缺点是,无论谁编写符合协议的类,都必须添加一个简单的存根方法,其中包含 return nil 或其他内容。

You have ... options.

Optional methods are convenient for the person writing the class to conform to the protocol, annoying for the person making use of the protocol. So it depends who you are trying to please.

Optional methods are not as bad as checking type. Imagine how the code would look when accessing a contactable entity object. When you use an optional method, you have to have an if case and an else case. It's not as convenient as just going ahead and assuming you can call the method. But it's way more convenient than checking type. That would be one if case for each different type of entity (and an else case, which might be an assertion). Additionally, if you use optional methods, information about the entity is encapsulated in its class. If you check type before calling a method, then the information about what type of contact information an entity provides is outside the class in the calling code. If you upgrade the entity to provide an additional type of contact, that improvement is not available until you update the calling code.

Option B is to make all the methods required, but give them the option of returning a value that indicates that no information is available, such as nil. Of course that still means an if case to check for a nil result, it's just less verbose. An even better solution for this problem is to have the methods return collections of multiple contacts. After all, people can have more than one phone number. Then to indicate that a contact type is not applicable, you would just return an empty collection.

The downside is that whoever writes the class that conforms to the protocol has to add a simple stub method that says return nil or something.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文