views:

301

answers:

2

Hey,

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'

+1  A: 

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.

e.James
Yes it does import Class2.h
Ghommey
Ah, then there is your problem. You have a header dependency loop! You'll need to separate things out. I'll post some more detail in a sec.
e.James
Thx alotthat makes sense
Ghommey
You are welcome. Good luck sorting things out :)
e.James
If you really have a circular dependency between two classes, I suggest that you refactor your class design to eliminate this anti-pattern. When two classes #import each other, they are essentially the same class. Wikipedia has some more detail at http://en.wikipedia.org/wiki/Circular_dependency and SO has a thread about this at http://stackoverflow.com/questions/1223251/software-design-problem-circular-dependency
Shaggy Frog
@Shaggy Frog: That is good advice. Circular dependencies shouldn't happen if you design your classes properly.
e.James
+1  A: 

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.

Shaggy Frog
+1 for that link! Nice find.
e.James
Class2 does not implement the method as it only sends the method to the delegate
Ghommey