Circular Imports

I'm getting a problem with "circular" or two-way imports. That is, two separate classes that each use the other. If I eliminate all references from one class to the other, thereby making it a single-way import, then I've got no errors and everything runs fine. However, once I put the two-way importing back in, random unrelated compiler errors pop up.

Example:

Code:

//ClassA.h

#import "ClassB.h"

@interface ClassA : NSObject
{
//blah blah
}
//blah blah
@end

Code:

//ClassB.h

#import "ClassA.h"

@interface ClassB : NSObject
{
//blah blah
}
//blah blah
@end

That will create an error, whereas if I either don't import ClassA or ClassB, in one file or the other, all problems are solved.

It seems to me that there has to be a way around this. It's fairly ridiculous if you can't have a two-way link. Like what if your World contains an array of Entities, and the Entities need to know what World they're in? Similarly, what if you've got a circular import chain that goes through 5 or 6 classes? i.e. A imports B, B imports C, C imports D, D imports E, E imports A. Will that break it as well?

Best practice is @class everything you can, which is pretty much everything other than your superclass and any implemented protocols. #import in the implementation.

Says Apple: "The @class directive minimizes the amount of code seen by the compiler and linker, and is therefore the simplest way to give a forward declaration of a class name. Being simple, it avoids potential problems that may come with importing files that import still other files. For example, if one class declares a statically typed instance variable of another class, and their two interface files import each other, neither class may compile correctly." (http://developer.apple.com/documentation...ion_3.html)

Another related question. It seems properties and functions aren't found correctly when I use an @class. I replace it with an #import, and everything is fine. I assume that this means that in the .m file I should always use #import and in the .h always use @class? Also when making a subclass I need to do #import or it doesn't work correctly either.

@class is a forward declaration. That means, you are telling the compiler that "This class exists somewhere, I'm not going to give you any details about it, other than it's okay to declare instance variables of that type."

So basically, if a class doesn't exist, and you try and declare an instance of it, the compiler throws up an error. Forward declaring a class just ignores those errors.

If you are using a class as a super class, you need to import it. Importing a header file essentially copies and pastes the contents of that file to wherever the import statement is. You need to know everything about a class if it is going to be a super class, because the subclass needs to declare those instance variables and methods from the super class.

So, the general rule is this: If your class has instance variables of some type, you should forward declare that type to shut the compiler up. If your class needs to know about anything else in a file (instance variables a class has, protocols declared in that file, methods that a class implements), it needs to import it. If you forward declare a class, you need to import it in your .m file.