Tuesday, June 29, 2010

The difference between #import, #include and @class in Objective C

If you are an Apple iPhone/ iPad/ Safari developer wondering whats the difference between the Objective C constructs #include#import and @class, read on :

#import and #include

C has the #include preprocessor for including libraries. Objective C supports both #import and #include preprocessors. Apple's recommended way of loading headers in Objective C is to use #import. If you use #include, your header files would need header guards to check if a related header file is already included or not. The #import preprocessor automatically keeps track of headers that have been included and ignores if a header is imported more than once. GNU Objective C compiler supports #import however, it would emit a warning discouraging the use of #import as its strictly not "C" compatible. You can turn off the warning by using the -Wno-import option in the GNU Objective C compiler.

TIP :

If your code is strictly in Objective C and you are looking at strictly supporting Apple SDKs, use #import as the pre-processor. You can turn off the warning by using the -Wno-import option in the GNU Objective C compiler.


#import and @class

As discussed before, #import is a preprocessor that requires the compiler to include the header file. But what if, the class itself is not available to be included or there is a circular reference between class A and class B?

Thats when the construct @class is useful. @class is a "forward declaration" and whenever the compiler encounters an @class forward declaration, the compiler just notes that the actual declaration of the class is coming forward and hence doesnt worry about anything about that class, other than to reserve the memory allocation for a pointer whenever an instance of such forward declared classes are referred to.

For example, in the code

@class A
@interface B :NSObject {
A * instance;  
}

Here, since class A is a forward declaration, the compiler just reserves the memory for a pointer and ignores further validation.

Forward declaration not only reduces the pre-processing overheads and makes compilation & linking faster, but also helps better development as the implementation of class A can be "defered" without impacting the development of class B.

TIP : 


In general use this as a rule of thumb, whenever you are in doubt about #import vs @class :

  1. Always import the header files and framework classes by using #import.
  2. Whenever you need to "send messages" to any class in your implementation, import the relevant headers using #import.
  3. For all other scenarios, use forward declarations with @class.

No comments:

Post a Comment