views:

958

answers:

6

I have a class with an delegate property. Anyone who wants to be a delegate must conform to a protocol. I defined everything like this:

#import <UIKit/UIKit.h>

@protocol TheDelegateProtocol;

@interface MyClass : UIView {
    id<TheDelegateProtocol> theDelegate;
}

@property (nonatomic, assign) id<TheDelegateProtocol> theDelegate;


@end


@protocol TheDelegateProtocol<NSObject>
@required

- (void)fooBarWithFoo:(CGFloat)foo;
@end

Now the crazy thing is: I have another class that wants to be the delegate. So it conforms to that protocol, like this:

#import <Foundation/Foundation.h>

@class MyClass; // forward declaration. importet in implementation.
@protocol TheDelegateProtocol; // need forward declaration here, right?

@interface OtherClass : NSObject <TheDelegateProtocol> {
    // ivars
}

@end

I can't get that to work. It says: "No definition of protocol 'TheDelegateProtocol' found". Well, that protocol is defined in MyClass, and I am importing MyClass in the implementation. Any idea what's wrong there?

Figured out something: In a method where I try to assign the protocol, it is telling me, that OtherClass does not conform to the protocol. But it does! That makes no sense. I also added the protocol method in the header....

+1  A: 

Is this a warning? because sometimes it does that when you have circular references and stuff, and it gets confused, but in reality its ok, have u tried running it to see if it works? In my project i have a bunch of warning about protocols not found, they are there though and it works fine... What you can do to get rid of the warning is try defining the protocol outside the class on some other .h file. You also dont really need the forward declaration, you can just do #import of the .h file its defined in

Daniel
It's not great practice to ignore warnings, whatever they are...
ing0
+1  A: 

Put the definition of the protocol in a separate file.

#import that file into any header file that needs it.

Dave Gamble
+3  A: 

I think you need to #import the header file that defines the protocol. How can the compiler know which methods are available without it?

If you use another class (i.e., as an ivar or as a parameter to a method) then you can use a forward declaration. But if you subclass then you need to #import.

Stephen Darlington
How would I put that protocol definition in an own file? Would I have just an .h file, but no .m file for it? The .m file would not make any sense for a protocol.
HelloMoon
Yes, that's right.
Stephen Darlington
A: 

Your two classes differ in their use of the protocol. MyClass does not implement the protocol, it has an attibute that is a pointer to a class that implements the protocol. OtherClass should implement the protocol.

OtherClass needs to have available before its interface is defined all the details of the protocols, interfaces and classes that it inherits from. Thus you need the protocol in a header to be #imported in OtherClass.h

MyClass just needs to know the protocol exists in its interface.

Note on Stephen's reply subclassing is the case you can't use forward declarations of classes. (In the example OtherClass is a subclass of NSObject)

Mark
Yes, subclass was the wrong word. I reworded my answer to make it clearer what I meant.
Stephen Darlington
+1  A: 

The compiler's warning is correct. OtherClass doesn't conform to the protocol because it doesn't declare the required fooBarWithFoo method that the protocol expects.

Have you tried it this way?

#import "MyClass.h"

@interface OtherClass : NSObject <TheDelegateProtocol> {
    // ivars
}

- (void)fooBarWithFoo:(CGFloat)foo; // <<< missing bit

@end
Ramin
A: 

He doesn't need to declare the methods to conform to the protocol. He only need to implement them in the .m file.

nobre