1

First, I have seen this question as well as this, but my problem is not addressed there.

I have a protocol ProtocolA defined in its own header file. Then I have two classes ClassA and ClassB which both conform to this protocol so the protocol-header is imported in their header files.

Now it gets a bit complicated. ClassA is used (and thus imported) in a third ClassC. This class conforms to a second protocol ProtocolB. This protocol also has its own header file where it uses and imports ClassB. So my ClassC imports (either directly or indirectly) both ClassA and ClassB (which both import ProtocolA). This gives me the following warning regarding ProtocolA:

warning: duplicate protocol definition of '…' is ignored

Why is this happening? It was my understanding that the #import macro was invented exactly for avoiding this kind of problems which we had with #include. How can I solve the issue without using an include guard? I can't really remove any of the imports.

EDIT: here is the code to illustrate the situation:

ProtocolA.h

@protocol ProtocolA <NSObject>
- (void)someMethod;
@end

ClassA.h

#import "ProtocolA.h"

@interface ClassA : NSObject <ProtocolA>
...
@end

ClassB.h

#import "ProtocolA.h"

@interface ClassB : NSObject <ProtocolA>
typedef enum Type {
    TypeB1,
    TypeB2
} TypeB;
...
@end

ProtocolB.h

#import "ClassB.h"

@protocol ProtocolB <NSObject>
- (TypeB)someMethod;
@end

ClassC.h

#import "ProtocolB.h"

@interface ClassC : NSObject <ProtocolB>
...
@end

ClassC.m

#import "ClassC.h"
#import "ClassA.h" // the warning appears here

@implementation ClassC
...
@end
Community
  • 1
  • 1
pajevic
  • 4,607
  • 4
  • 39
  • 73
  • You'll need to post the code; your description is hard to follow. – trojanfoe Nov 05 '15 at 14:36
  • I have added example code. Although I admit, it can still be hard to follow. – pajevic Nov 05 '15 at 14:59
  • Using forward declarations is the answer. If you only ever use `ClassA *` within `ClassB.h` then use `@class ClassA;` at the start of the file. Same for protocols. – trojanfoe Nov 05 '15 at 15:01

1 Answers1

0

do not Import ClassB in ProtocolB header, just use @class ClassB; in it and remove #import "ClassB"

ogres
  • 3,660
  • 1
  • 17
  • 16
  • There is no indication the OP is importing the class header from the protocol header, unless I missed it... – trojanfoe Nov 05 '15 at 14:40
  • read again , "This class conforms to a second protocol ProtocolB. This protocol also has its own header file where it uses and imports ClassB." – ogres Nov 05 '15 at 14:41
  • `ClassB` header is indeed imported in `ProtocolB`. This is done because one of the methods of `ProtocolB` return an enum type which is defined in the header of `ClassB`. So `@class ClassB;` won't really work, unless I can somehow forward declare an enum. – pajevic Nov 05 '15 at 14:43
  • Move your struct declaration in its own file – ogres Nov 05 '15 at 14:46
  • Yeah using `@class SomeClass;` is often required when declaring a protocol. – trojanfoe Nov 05 '15 at 14:48
  • ogres, moving the enum to its own file was the solution, thanks! If you edit your answer I will accept it. – pajevic Nov 05 '15 at 15:08
  • or just front declare the protocol – Daij-Djan Nov 05 '15 at 15:11
  • 1
    Daij-Djan, you cannot forward declare a protocol when conforming to it as the class will not know its methods etc. It only works when your are solely using it as a type. – pajevic Nov 05 '15 at 15:16