22

I'm trying to extend NSImageView so I can delegate the drag/drop responsibility to the controller. It all works fine with the one problem that the compiler is now displaying warnings about sending messages to objects with type id. To solve this I assumed I would simply have to suffix the ivar's type with the name of the protocol. However, this fails miserably with the message that it cannot find the definition for the protocol.

#import <Cocoa/Cocoa.h> @interface DragDropImageView : NSImageView { id <DragDropImageViewDelegate> _delegate; } @property (readwrite, retain) id <DragDropImageViewDelegate> delegate; @end @protocol DragDropImageViewDelegate @optional - (NSDragOperation)dragDropImageView:(DragDropImageView *)ddiv validateDrop:(id <NSDraggingInfo>)info; - (BOOL)dragDropImageView:(DragDropImageView *)ddiv acceptDrop:(id <NSDraggingInfo>)info; - (void)concludeDragOperation:(id <NSDraggingInfo>)sender; @end 

Any pointers where I might be going wrong? I'm sure it must be something simple, but I'm quite new to obj-c.

2
  • +1 for nice question. Commented Apr 10, 2013 at 11:48
  • the keywords are: forward declaration. Commented Feb 21, 2014 at 23:11

2 Answers 2

31

You're on the right track but you're getting hung up by the C compiler, which is a little archaic. The compiler is choking because the definition of the protocol is not available at the time you use it. @protocol DragDropImageViewDelegate must be defined before you can use id< DragDropImageViewDelegate> as a type. You can move the @protocol definition before the usage (i.e. before your @interface), or add a

@protocol DragDropImageViewDelegate; 

before the @interface (a forward declaration) and leave the @protocol declaration where it is.

Sign up to request clarification or add additional context in comments.

3 Comments

Beautiful. Thank you. I actually had to go for the forward declaration as moving the protocol declaration above the @implementation introduced the issue of the protocol now referring to DragDropImageView before it had been defined. Thanks for your help!
Yes, of course it would. In general, the forward declaration is the solution to circular dependencies of this type.
+1 for Nice Answer. I have a little query, When we write \@protocol DragDropImageViewDelegate; before \@interface, then what is done by compiler?
10

As a general rule, I define the protocol first, preceeded by

@class DragDropImageView; 

But you can do the reverse and preceed with:

@protocol DragDropImageViewDelegate; 

To my mind, the protocol is an important part of the declaration, and tends to be quite short, so I prefer it to go first rather than be lost at the bottom of the header file, but its a matter of taste.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.