Crystal
Crystal

Reputation: 29458

Forward declaring a protocol in objective-c

My class .h looks like:

@protocol AppInfoDelegate;
@class InfoTextView;


@interface AppInfoViewController : UIViewController <AppInfoDelegate> {

}


@property (nonatomic, retain) NSArray *textObjectsArray;
@property (nonatomic, retain) InfoTextView *itView;
@property (nonatomic, retain) UIButton *pgBackButton;
@property (nonatomic, retain) UIButton *pgFwdButton;

@end

@protocol AppInfoDelegate <NSObject>
- (void)closeButtonPressed:(id)sender;

@end

I get a warning that the protocol definition for AppInfoDelegate cannot be found. What is the proper way to do this and why cannot it not be found? Do I need to have the whole definition of the protocol before the interface? Thanks!

Upvotes: 2

Views: 5158

Answers (4)

Conrad Shultz
Conrad Shultz

Reputation: 8808

Using @protocol MyProtocol; is useful when you are asserting, for example, that a method will take id <MyProtocol> as an argument.

It is not useful when you are claiming that your class conforms to <MyProtocol>. The reason for this is that the compiler needs the full protocol declaration in order to verify that your class actually conforms to the protocol. (This compile-time check is one great reason to use formal protocols instead of the older informal ones.)

You can fix in two ways. One, as @skram suggests, is to just forward-declare the whole thing. This works, but it's also rather limited in my view. Why bother with a protocol in that case - just put everything in the class @interface and be done with it.

The second approach, which I prefer, is to actually have a separate header, such as MyProtocol.h. You can then freely import this into any header or implementation files as needed. This allows you to reuse a protocol easily (and avoid the headaches of circular imports that sometimes arise).

Upvotes: 17

cdelacroix
cdelacroix

Reputation: 1289

Yes, superclass and adopted protocol definitions need to be defined (verbatim or by using #import) before the class definition. They cannot be forward-declared.

Upvotes: 0

skram
skram

Reputation: 5314

Try this:

@protocol AppInfoDelegate <NSObject>
- (void)closeButtonPressed:(id)sender;

@end   

@class InfoTextView;


@interface AppInfoViewController : UIViewController <AppInfoDelegate> {

}


@property (nonatomic, retain) NSArray *textObjectsArray;
@property (nonatomic, retain) InfoTextView *itView;
@property (nonatomic, retain) UIButton *pgBackButton;
@property (nonatomic, retain) UIButton *pgFwdButton;

@end

Upvotes: 0

onetwopunch
onetwopunch

Reputation: 3329

I've always seen the whole protocol definition before the @interface. I believe you can also put it into a separate file though

Upvotes: -1

Related Questions