简体   繁体   中英

Declaring a delegate protocol

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

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.

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.

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.

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

And then in Parent.h:

@interface Parent : SomeBaseClass<FooProtocol> {
}

which allows Child to do this:

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

and use it

[fooHandler foo: 1 bar: YES];

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 .

No difference. It's just a matter of how you like to organize your headers.

For example, I like to keep everything related to "one functional entity" (whatever that means, the definition varies :-)) in one file. A class that is using delegates that implement a protocol would therefore declare the class and the protocol in the same header, since they are pretty much just different bricks of the same building.

The only difference between having your protocol in a separate header file to your class's header file is it allows for including the protocol to be optional, this could aid in resolving any naming clashes, but prefixing your protocols should be the solution for that.

The convention seems to be to include relevant protocols inside the class's header file, as that way it's more organized and kept together, but if you have extremely large protocols it may make more sense to have them in separate files in order to make your class headers easier to read.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM