Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Aquis

macrumors member
Original poster
Aug 7, 2007
63
0
Staffordshire, UK
Hey, let's say I have two objects, ObjectA and ObjectB, and I therefore have the files:
ObjectA.m
ObjectA.h
ObjectB.m
ObjectB.h
I also have another file which imports all the object headers for me, Headers.h. Inside, we have:
Code:
#import "ObjectA.h"
#import "ObjectB.h"

Okay - ObjectB is a subclass of ObjectA, and in both their header files, they #import "Headers.h" (so I don't have to #import long lists of headers when I have lots of classes, etc.)

The problem is when I compile. From what I can gather, Xcode compiles ObjectA.m, is taken to ObjectA.h, then Headers.h, and then ObjectB.h - but because ObjectB is a subclass of ObjectA, and ObjectA's @interface has not yet been "read", I get the error:
error: cannot find interface declaration for 'ObjectA', superclass of 'ObjectB'

So my question is, how can I get round this problem?

Thanks!
 

davedelong

macrumors member
Sep 9, 2007
50
0
Right here.
Ah, gotta love circular dependencies.

Sorry, but importing "Header.h" is causing your problem. You need to take out the declaration to ObjectA in your Header.h file, and, if necessary, add it as a forward declaration in ObjectB.h:

Code:
//ObjectB.h
@class ObjectA;  //this is like a promise to the compiler that you'll import it later

@interface ObjectB : ObjectA {
...
}
...
@end

Code:
//ObjectB.m
#import "ObjectB.h"
#import "ObjectA.h"

@implementation ObjectB
...
@end

HTH,

Dave
 

Aquis

macrumors member
Original poster
Aug 7, 2007
63
0
Staffordshire, UK
Thanks for the reply, but I'm still having problems...

I have it basically as you wrote, @class directives before the @interface (I had those anyway), and removed the #import "Headers.h" from ObjectB.h and put #import "ObjectA.h" after #import "ObjectB.h" in ObjectB.m. But I still get the same error? Plus more, under that error, I also get two more errors (exactly the same), each reading:

error: no super class declared in @interface for 'ObjectB' (when compiling "a file included from" ObjectB.m)...
 

davedelong

macrumors member
Sep 9, 2007
50
0
Right here.
Is ObjectB inheriting from ObjectA? Like so:

Code:
//ObjectB.h

#import <Cocoa/Cocoa.h>

@class Object A;

@interface ObjectB : ObjectA {
...
}
...
@end

Dave
 

Aquis

macrumors member
Original poster
Aug 7, 2007
63
0
Staffordshire, UK
Yes, here are the files I'm using (renamed and stripped of contents):

ObjectA.h
Code:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@class ...; // Other, unrelated classes...


@interface ObjectA : NSObject {
	...
}

...

@end

ObjectA.m
Code:
#import "ObjectA.h"

#import "..." // A few other unrelated class header files...


@implementation ObjectA

...

@end

ObjectB.h
Code:
#import <UIKit/UIKit.h>

@class ObjectA;
@class ...; // Other unrelated objects...

@interface ObjectB : ObjectA {
	...
}

...

@end

ObjectB.m (with error)
Code:
#import "ObjectB.h"
[COLOR="Red"][B]error: cannot find interface decleration for 'ObjectA', superclass of 'ObjectB'[/B][/COLOR]
#import "ObjectA.h"
#import "..." // Other class headers...


@implementation ObjectB

...

@end

Thanks for any help!
 

crees!

macrumors 68020
Jun 14, 2003
2,018
245
MD/VA/DC
I also have another file which imports all the object headers for me, Headers.h. Inside, we have:
Code:
#import "ObjectA.h"
#import "ObjectB.h"

Okay - ObjectB is a subclass of ObjectA, and in both their header files, they #import "Headers.h" (so I don't have to #import long lists of headers when I have lots of classes, etc.)

I am strongly against lumping all headers into one file. Obviously, you see the issue it's already causing. Second, not all headers will be needed in each of your classes. Third, it makes it difficult at a glance by someone reading your code what the class is about and the functionality it might take on. Fourth, it's just bad practice. Import them like normal and go from there.
 

crees!

macrumors 68020
Jun 14, 2003
2,018
245
MD/VA/DC
Yes, here are the files I'm using (renamed and stripped of contents):

ObjectA.h
Code:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@class ...; // Other, unrelated classes...


@interface ObjectA : NSObject {
	...
}

...

@end

ObjectA.m
Code:
#import "ObjectA.h"

#import "..." // A few other unrelated class header files...


@implementation ObjectA

...

@end

ObjectB.h
Code:
#import <UIKit/UIKit.h>

@class ObjectA;
@class ...; // Other unrelated objects...

@interface ObjectB : ObjectA {
	...
}

...

@end

ObjectB.m (with error)
Code:
#import "ObjectB.h"
[COLOR="Red"][B]error: cannot find interface decleration for 'ObjectA', superclass of 'ObjectB'[/B][/COLOR]
#import "ObjectA.h"
#import "..." // Other class headers...


@implementation ObjectB

...

@end

Thanks for any help!

You don't need to include #import ObjectA.h in ObjectB.m because it's already included in ObjectA.m. Same goes with UIKit. That is unless I'm getting my languages mixed up :p
 

Aquis

macrumors member
Original poster
Aug 7, 2007
63
0
Staffordshire, UK
A ha! Just figured it out, can't believe I didn't see it before...

You don't need to include #import ObjectA.h in ObjectB.m because it's already included in ObjectA.m. Same goes with UIKit. That is unless I'm getting my languages mixed up

Actually, you do (I think) - but if you look at the file with the error in, ObjectB.m, you will see that it hasn't imported ObjectA.h when it makes the interface using it, so, I rearranged the order in which they go and...it worked!

@class ObjectA; //this is like a promise to the compiler that you'll import it later

If would appear that in order to inherit from an object, the @class directive doesn't work - you need to have already defined the object.

I don't particularly like Java, but at least it automatically includes all the files you ever need!

Thanks!
Aquis
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
I don't particularly like Java, but at least it automatically includes all the files you ever need!

No it doesn't. You might have an IDE that does, but you have to import anything you want to use in a particular file.

-Lee
 

davedelong

macrumors member
Sep 9, 2007
50
0
Right here.
A ha! Just figured it out, can't believe I didn't see it before...

Actually, you do (I think) - but if you look at the file with the error in, ObjectB.m, you will see that it hasn't imported ObjectA.h when it makes the interface using it, so, I rearranged the order in which they go and...it worked!

If would appear that in order to inherit from an object, the @class directive doesn't work - you need to have already defined the object.

Good catch! I'll have to remember that about using the @class and inheriting! :)

Dave
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
Well, to be a troll, java.lang.* is automatically imported, but yes: everything else does need to be manually imported.

Touché. I don't think i've ever gotten away without any imports other than the implicit java.lang.*, but it would be a bit annoying if it was not and anytime you reached for a java.lang.String or java.lang.Integer you'd have to do an import. I'm sure most IDEs would just stick java.lang.* in there for you if that was the case.

-Lee
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.