I've been teaching myself Objective-C over the past month or so (I'm a Java head) and I've got my brain wrapped around most of it now. One thing that's confusing me at the moment: What's the difference between importing a class via @class vs doing a #import?
Is one better than another one, or do I need to use one instead of the other in certain cases? I've been using just #import so far.
#import
brings the entire header file in question into the current file; any files that THAT file #import
s are also included. @class, on the other hand (when used on a line by itself with some class names), just tells the compiler "Hey, you're going to see a new token soon; it's a class, so treat it that way).
This is very useful when you've got the potential for 'circular includes'; ie, Object1.h makes reference to Object2, and Object2.h makes reference to Object1. If you #import
both files into the other, the compiler can get confused as it tries to #import
Object1.h, looks in it and sees Object2.h; it tries to #import
Object2.h, and sees Object1.h, etc.
If, on the other hand, each of those files has @class Object1;
or @class Object2;
, then there's no circular reference. Just be sure to actually #import
the required headers into your implementation (.m) files.
@class
is called a forward declaration. You're basically telling the compiler that the class exists but not anything about the class. Thus, it doesn't know stuff like its superclass and what methods it declares.
As a general rule, use @class
in the .h and #import
in the .m, if at all possible. Like Louis said, it'll help speed up compile times. There are times when you need to #import
a class in the header, though. Cases I can think of right now are:
In these cases, you must #import
the header file where the class or protocol is declared because the compiler needs to know the full class hierarchy of its parent classes and implementing protocols.
FWIW, you can forward declare protocols, too, so long as your not implementing them:
@protocol SomeProtocol;
@interface ...
- (id<SomeProtocol>)someMethod;
@end
The other thing you want to keep in mind is that #imports slow down your compile times, since it means the the compiler needs to pull and work through a lot more header files. This is mostly masked by the use of precompiled headers, but I have occasionally been handed projects that corss imported every header instead of using @class where appropriate, and fixing them can improve compile time. It is subtle way the the system reinforces the fact that if you only use what you actually need things go faster.
As a general rule, I always use @class declarations in in my header files, and only #import the superclass. That falls in line with Ben's suggestions, but I thought it was worth noting that even if you are not worried about circular refs it is good idea to limit #imports in header files if you can.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With