jantimon
jantimon

Reputation: 38160

Is there a way to use a protocol definition of an other header file?

I have troubles using a foreign protocol in Objective-C.

Is there any other solution than adding additional Protocols?


Example:

Class1.h

#import "Class2.h"

@protocol Class1Delegate <NSObject>
    @required
    -(NSArray*) someMethod;
@end

@interface Class1 : NSObject
{
     Class2 *variable;

} ...

Class2.h

#import "Class1.h"
@interface Class2: NSObject {
    id <Class1Delegate> delegate;
}
@property (nonatomic,assign) id <Class1Delegate> delegate;

Error:

error: cannot find protocol declaration for 'Class1Delegate'

Upvotes: 1

Views: 1593

Answers (2)

James Eichele
James Eichele

Reputation: 119164

It should work the way you have described it. Are you sure there isn't something else going on?

Does Class1.h #import Class2.h?

update:

If Class1.h also imports Class2.h, then you have a header dependency loop:

Class1.h imports Class2.h
Class2.h imports Class1.h

Here is the problem:

  1. The compiler starts working on Class1.h
  2. It runs into the line: `#import "Class2.h"
  3. It opens up Class2.h and starts working there
  4. It finds the line: #import Class1.h
  5. It ignores that line (to avoid an infinite loop)
  6. It throws an error because Class2.h requires things from Class1.h which have not yet been compiled

How you solve it is really up to you, but this kind of loop is an indication that something is wrong with your design. A quick fix might be as follows:

Class1.h

@protocol Class1Delegate <NSObject>
@required
-(NSArray*) someMethod;
@end

#import "Class2.h" // moved here to avoid a cyclic dependency

@interface Class1 : NSObject
...

You simply move the #import line after the protocol has been declared.

Upvotes: 2

Shaggy Frog
Shaggy Frog

Reputation: 27601

This should work fine, as this pattern is used all the time (e.g. UIScrollViewDelegate defined in UIScrollView.h, but you can #import it and use it in a view controller class declaration).

Out of curiosity, does Class2.m actually implement the required someMethod method?

Can we see more of the error output?

P.S. You should not retain the delegate. Your @property directive should be (nonatomic, assign). See Ownership of Delegates, Observers, and Targets.

Upvotes: 1

Related Questions