What is the difference between #include vs #include” ” vs #import vs #import” ” vs @class

Modules and Precompiled Headers

In WWDC 2013, what prompted me was noticing that Xcode no longer adds a Prefix.pch file to new projects by default which has a lot to do with modules.

#Import versus #Include

To understand why modules are useful it is worth first recapping the traditional way of working with frameworks and libraries. As I am sure everybody reading this knows it involves including (via a #include) the framework or library header in your source file and then at build time linking with the library.

The #import directive used by Objective-C is almost identical to the classic #include mechanism it inherited from the C programming language. The only difference is that it makes sure the same file is never included more than once. This is a small convenience to avoid the common C technique of including a header guard for the preprocessor.

Explanation: 

Having the preprocessor (The preprocessor provides the ability for the inclusion of header files, macro expansions, conditional compilation, and line control.) parse each header file in each source file quickly becomes slow and inefficient as the project grows as many source files include the same header files.

Precompiled Headers(.pch)

Precompiled headers are a partial solution to the problem of slow build times. They speed up the time it takes to compile a project when all or nearly all source files need to include some common headers. For example, an iOS project is likely to include in most if not all source files. This means parsing and compiling the UIKit.h header many times when building the project which is wasteful and slow. A precompiled header file, as the name suggests, collects the common headers into a separate file. Precompiling this file just once and then automatically including it in all source files in the project significantly speeds up the build process for many projects.

Here is a typical Prefix.pch file from an old project that imports UIKit and Foundation headers as well as checking for at least iOS 5:

Conditional Compilation Statement i.e if micro name is defined or not

#if, #ifdef, #ifndef, #else, #elif, #endif

The beginning of the block of program text is marked by one of three directives:

  • #if
  • #ifdef
  • #ifndef

Optionally, an alternative block of text can be set aside with one of two directives:

  • #else
  • #elif

The end of the block or alternative block is marked by the #endif directive.

#ifdef -> if defined
#ifndef -> if not defined
#undef -> defined macro is removed and thus it became undefined
Example 1
#include<stdio.h>
#define NUM 10

void main()
{
// Define another macro if MACRO NUM is defined

#ifdef NUM
      #define MAX 20 
#endif

printf("MAX number is : %d",MAX);
}

Output :

MAX Number is 20
Example 2
#include<stdio.h>

void main()
{

#ifdef MAX 
    #define MIN 90
#else
    #define MIN 100
#endif

printf("MIN number : %d",MIN);
}

Output :

MIN number : 100

 

The ability to have something globally included by placing it in the pch file is a useful but easily abused facility. Maintaining and optimising the prefix header file also puts a lot of the work on the developer that the tools should be handling for us.

Modules

A module offers a better way to work with system frameworks and libraries by replacing the preprocessor text inclusion mechanism with what Clang refers to as a semantic import. To import a module you use the @import declaration instead of the #include or #import preprocessor directives (note the semicolon):

@import UIKit;

When the compiler sees a module import it loads a standalone precompiled version of the framework. It also automatically takes care of linking to the module meaning you no longer need to manually add the framework in Xcode. Since the module is compiled just once there is no longer any advantage to including the framework header in prefix.pch. As a result the Precompile Prefix Header build setting now defaults to NO in Xcode.

Using Modules

Opting into using modules is as easy as setting the Apple LLVM 6.0 – Language – Modules Xcode build settings:

Both the Enable Modules and Link Frameworks Automatically settings default to YES in new Xcode projects. In fact once modules are enabled any #import or #include directives are automatically converted to @import declarations. This means you can adopt modules without having to make source code changes. For example a header file that has old style preprocessor imports for UIKit and Core Data frameworks:

#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>

With modules enabled this is automatically mapped to import declarations:

@import UIKit;
@import CoreData;

One limitation of modules is that they are not available for user frameworks but the Apple system frameworks have been available as modules since iOS 7 (and OS X 10.9).

Adding a Pre-Compiled Header to a Project

Now that modules are available there is no need to continue to list system frameworks in a precompiled prefix header. If you need to add a prefix header to an Xcode project you can still do that (at least at time of writing with Xcode 6.1) by manually modifying the Precompile Prefix Header flag to YES and specifying the path in Prefix Header:

So conclusion is:

Modules are a packaging together of the framework executable and it’s headers and are safer and more efficient than #import.

@import solves following problems:

  • Imports complete semantic description of a framework
  • Doesn’t need to parse the headers
  • Loads binary representation
  • More flexible than precompiled headers
  • No need to maintain your .pch files

It’s also possible to import sub modules of some module. For instance we want to import MKMapView submodule of MapKit. We can do it in the following way:

@import MapKit.MKMapView;

What to do if you already have a lot of code with #import or #include? Actually Apple takes care for it. All #import and #include directives are mapped to use @import automatically. That means that you don’t have to change your source code.

What is the difference between

#include< >
#include" "

#import< >
#import" "

@class

#import ensures that a file is only ever included once so that you never have a problem with recursive includes.

#import "" first check the header in project folder then goes to system library, and the #import<> checks for system headers”.

Q) What is difference between ” ” vs < > ?

  1. "" are used for local files. That means files in the current directory.

< and > are used for system files found in the folders of your path. /usr/include is probably one of them.

2. It means the difference is in the order, in which the compiler searches different folders for files. The “fine.h” form gives precedence to the current folder (the one where the containing source file is). The <> form searches the system which include its own folder first.

3. So far my observation is that the quote marks "" searches for files in your project that you’ve got the implementation source to, and angle brackets <>when you’re referencing a library or framework.

Q) What is difference between include vs import?

1.#import keeps track of which headers have already been included and is ignored if a header is imported more than once in a compilation unit. This makes it unnecessary to use header guards.

2. When using #import, the header include guard is unnecessary. Otherwise, it’s just like #include.

3. #include allow you to include the same file many times. #import ensures that the preprocessor only includes a file once. C programmers tend to use #include. Objective-C programmers tend to use #import.

Compiling a file in Objective-C is done in two passes. First,
the preprocessor runs through the file. The output from the preprocessor goes into the real compiler.

Q) What is difference between import vs @class?

“#import” brings the entire header file into the current file.

@class allows you to declare an Objective-c class name without the need to #import the header file that defines the class. You would use this where you only need the class name defined for the purposes of declaring a pointer to the class or a method parameter of the class. It saves a lot of compile time vs the #import, and it sometimes helps avoid messy include circularity issues.

circular includes‘; i.e, 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.

Recursive Includes

So, this preprocessor #include directive is great. It lets you modularize your code, include system headers, and fosters reusability. But what happens when you have a pair of files that look like this:

// FirstFile.h
#include "SecondFile.h"
/* Some code */
// SecondFile.h
#include "FirstFile.h"
/* Some other code */

Well, the preprocessor first goes out and sees that FirstFile.h wants to include SecondFile.h inside of it. But when it goes to do that, it sees that SecondFile.h also tries to include FirstFile.h, which includes SecondFile.h, which includes FirstFile.h, which includes….ok, well, you get the picture. This is called a Recursive Include.

The recursive include is the problem that Objective-C tried to solve with the introduction of the #import directive. Using #import, a file would be guarded against recursive includes by first checking to make sure the included file was not already defined. If it was not, the file would be included, otherwise it would be skipped.

For Example

If you say @class myClass, the compiler knows that it may see something like:

myClass *myObject;

It doesn’t have to worry about anything other than myClass is a valid class, and it should reserve room for a pointer to it (really, just a pointer). Thus, in your header, @class suffices 90% of the time.

However, if you ever need to create or access myObject’s members, you’ll need to let the compiler know what those methods are. At this point (presumably in your implementation file), you’ll need to #import "myClass.h", to tell the compiler additional information beyond just “this is a class”.

@class MyViewController;

Is a forward declaration for the object MyViewController. It is used when you just need to tell the compiler about an object type but have no need to include the header file.

If however you need to create an object of this type and invoke methods on it, you will need to:

#import "MyViewController.h"

In other words, you always #import the files you’re using in your implementation, and if you need to reference a class in your header file use a forward declaration as well.

for example when you create a protocol:

@class yourCustomView;

@protocol yourCustomViewDelegate <NSObject>

@required

- (void) somethingDidInView:(UIView*)view;

@end

@interface yourCustomView : FIView
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s