5

我想知道protocol在同一个类中声明 a 和在单独的文件中声明它有什么区别;例子 :

#import <UIKit/UIKit.h>

@class MyClassA;

@protocol MyDelegate <NSObject>

@required
- (MyClassA*)myMythod;

@optional
- (void)anOtherMethod:(NSString*)ID;

@end

@interface MyClassB : UIViewController <UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, assign) id <MyDelegate> delegate;
......

在这里,我在与 MyClassB 相同的文件中声明协议委托,我可以在单独的源文件中声明它(协议委托)。在与类相同的文件中声明它和在单独的文件中声明它有什么区别?谢谢!

4

3 回答 3

8

肯定有细微的差别。

如果您正在谈论的协议是一个特定类使用的委托,例如,MySpecialViewControllerMySpecialViewControllerDelegate,那么您可能非常希望将这两者的声明保留在同一个标​​头中。例如,如果另一个类要实现该协议,它可能会在逻辑上依赖于MySpecialViewController该类。因此,您不会引入任何其他依赖项。

但是,使用协议还有另一个重要原因(至少)。您可能正在尝试解耦两个类之间的双向依赖关系。当然,编译器不会让两个头文件#import相互连接。但是,即使您将一个类#import移到.m文件中,让两个类各自完全了解彼此的完整 API 通常是设计不佳的标志。

稍微解耦这种关系的一种方法是让一个类仅通过另一个类实现的协议来了解另一个类。也许Parent拥有并创建Child类,因此必须#import "Child.h"。但是,Child也需要foo:bar:调用Parent. 你可以做一个FooProtocol

@protocol FooProtocol
  - (void) foo: (int) arg1 bar: (BOOL) arg2;
@end

然后在 Parent.h 中:

@interface Parent : SomeBaseClass<FooProtocol> {
}

允许Child这样做:

@interface Child {
}
@property (assign) id<FooProtocol> fooHandler;

并使用它

[fooHandler foo: 1 bar: YES];

这使孩子没有直接依赖于Parent类(或 Parent.h)。但是,这仅在您将声明保留FooProtocol在 FooProtocol.h 中而不是在 Parent.h 中时才有效。同样,如果FooProtocol它只被 使用过Child,那么它保存在 Child.h 中是有意义的,但如果这个协议被除Child.

因此,总而言之,如果您想保留最大程度地分离类之间的相互依赖关系,或者鼓励在设计中更好地分离,请将您的协议保留在单独的标头中

于 2012-07-08T10:28:06.417 回答
1

没有不同。这只是您喜欢如何组织标题的问题。

例如,我喜欢将与“一个功能实体”相关的所有内容(无论这意味着什么,定义各不相同 :-))都保存在一个文件中。因此,使用实现协议的委托的类将在同一个标​​头中声明类和协议,因为它们几乎只是同一建筑物的不同砖块。

于 2012-07-08T09:32:04.527 回答
0

将协议放在单独的头文件与类的头文件之间的唯一区别是它允许将协议包含为可选的,这有助于解决任何命名冲突,但为协议添加前缀应该是解决方案。

约定似乎是在类的头文件中包含相关协议,因为这样可以更有条理并保持在一起,但是如果您有非常大的协议,将它们放在单独的文件中以使您的类头文件可能更有意义更容易阅读。

于 2012-07-08T09:35:16.773 回答