声明委托协议 [英] Declaring a delegate protocol

查看:84
本文介绍了声明委托协议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道在同一个类中声明协议并在单独的文件中声明它时有什么区别;例如:

I would like to know what is the difference when declaring a protocol in the same class and when declaring it in a separate file; example :

#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;
......

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

here I declare the protocol delagate in the same file with MyClassB, and I can declare it (the protocol delegate) in a separate source file. What is the difference between declaring it in the same file with the class and in a separate file? Thanks!

推荐答案

肯定存在微妙的差异。

There definitely are subtle differences.

如果您所谈论的协议是一个特定类使用的委托,例如 MySpecialViewController MySpecialViewControllerDelegate ,那么您可能非常希望将这两者的声明保留在同一标头中。例如,如果另一个类要实现该协议,则可能在 MySpecialViewController 类中依赖逻辑。所以,你没有引入任何额外的依赖关系。

If the protocol you are talking about is a delegate that is used by one particular class, for example, MySpecialViewController, and MySpecialViewControllerDelegate, then you might very well like to keep the declaration of both of those in the same header. If another class is going to implement that protocol, for example, it's probably going to depend logically on the MySpecialViewController class. So, you're not introducing any additional dependencies.

但是,(至少)使用协议还有另一个重要原因。您可能正在尝试解耦两个类之间的双向依赖关系。当然,编译器不允许两个头文件 #import 彼此。但是,即使您将一个类的 #import 移动到 .m 文件,通常也会表明设计很差,每个类都有两个类了解彼此的完整API。

But, there's another significant reason (at least) to use protocols. You might be trying to decouple a bidirectional dependency between two classes. Of course, the compiler doesn't let two headers #import one another. But, even if you move one class's #import to the .m file, it's often a sign of a poor design to have two classes each fully aware of one another's complete API.

一种方式将这种关系稍微解耦,只是让一个人通过协议了解另一个另一个实现。也许 Parent 拥有并创建 Child 类,因此必须 #importChild.h 。但是, Child 还需要在 Parent <上调用 foo:bar:方法/ code>。你可以做一个 FooProtocol

One way to decouple this relationship a little is to make one class aware of the other only through a protocol that the other implements. Perhaps Parent owns and creates the Child class, and thus must #import "Child.h". But, the Child also needs to call the foo:bar: method on the Parent. You could make a FooProtocol:

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

然后在Parent.h中:

And then in Parent.h:

@interface Parent : SomeBaseClass<FooProtocol> {
}

允许 Child 要做到这一点:

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

并使用它

[fooHandler foo: 1 bar: YES];

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

Which leaves the child with no direct dependency on the Parent class (or Parent.h). But, this only works if you keep the declaration of FooProtocol in FooProtocol.h, not in Parent.h. Again, if this FooProtocol was only ever used by Child, then it would make sense to keep it in Child.h, but probably not if this protocol was used by classes other than Child.

因此,总而言之,如果您希望保留最大限度地分隔类之间的相互依赖关系,或者希望在设计中更好地分离,请将协议保存在单独的标题中。

So, to summarize, keep your protocols in separate headers if you want to preserve the maximum ability to separate interdependencies between your classes, or to encourage better separation in your design.

这篇关于声明委托协议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆