[objective-c] What is the difference between #import and #include in Objective-C?

What are the differences between #import and #include in Objective-C and are there times where you should use one over the other? Is one deprecated?

I was reading the following tutorial: http://www.otierney.net/objective-c.html#preamble and its paragraph about #import and #include seems to contradict itself or at least is unclear.

This question is related to objective-c import include

The answer is


In may case I had a global variable in one of my .h files that was causing the problem, and I solved it by adding extern in front of it.


#include it used to get "things" from another file to the one the #include is used in. Ex:

in file: main.cpp

#include "otherfile.h"

// some stuff here using otherfile.h objects,
// functions or classes declared inside

Header guard is used on the top of each header file (*.h) to prevent including the same file more then once (if it happens you will get compile errors).

in file: otherfile.h

#ifndef OTHERFILE
#define OTHERFILE

// declare functions, classes or objects here

#endif

even if you put #include "otherfile.h" n time in your code, this inside it will not be redeclared.


If you are familiar with C++ and macros, then

#import "Class.h" 

is similar to

{
#pragma once

#include "class.h"
}

which means that your Class will be loaded only once when your app runs.


I agree with Jason.

I got caught out doing this:

#import <sys/time.h>  // to use gettimeofday() function
#import <time.h>      // to use time() function

For GNU gcc, it kept complaining that time() function was not defined.

So then I changed #import to #include and all went ok.

Reason:

You #import <sys/time.h>:
    <sys/time.h> includes only a part of <time.h> by using #defines

You #import <time.h>:
    No go. Even though only part of <time.h> was already included, as
    far as #import is concerned, that file is now already completely included.

Bottom line:

C/C++ headers traditionally includes parts of other include files.
So for C/C++ headers, use #include.
For objc/objc++ headers, use #import.


IF you #include a file two times in .h files than compiler will give error. But if you #import a file more than once compiler will ignore it.


There seems to be a lot of confusion regarding the preprocessor.

What the compiler does when it sees a #include that it replaces that line with the contents of the included files, no questions asked.

So if you have a file a.h with this contents:

typedef int my_number;

and a file b.c with this content:

#include "a.h"
#include "a.h"

the file b.c will be translated by the preprocessor before compilation to

typedef int my_number;
typedef int my_number;

which will result in a compiler error, since the type my_number is defined twice. Even though the definition is the same this is not allowed by the C language.

Since a header often is used in more than one place include guards usually are used in C. This looks like this:

 #ifndef _a_h_included_
 #define _a_h_included_

 typedef int my_number;

 #endif

The file b.c still would have the whole contents of the header in it twice after being preprocessed. But the second instance would be ignored since the macro _a_h_included_ would already have been defined.

This works really well, but has two drawbacks. First of all the include guards have to be written, and the macro name has to be different in every header. And secondly the compiler has still to look for the header file and read it as often as it is included.

Objective-C has the #import preprocessor instruction (it also can be used for C and C++ code with some compilers and options). This does almost the same as #include, but it also notes internally which file has already been included. The #import line is only replaced by the contents of the named file for the first time it is encountered. Every time after that it is just ignored.


I know this thread is old... but in "modern times".. there is a far superior "include strategy" via clang's @import modules - that is oft-overlooked..

Modules improve access to the API of software libraries by replacing the textual preprocessor inclusion model with a more robust, more efficient semantic model. From the user’s perspective, the code looks only slightly different, because one uses an import declaration rather than a #include preprocessor directive:

@import Darwin; // Like including all of /usr/include. @see /usr/include/module.map

or

@import Foundation;  //  Like #import <Foundation/Foundation.h>
@import ObjectiveC;  //  Like #import <objc/runtime.h>

However, this module import behaves quite differently from the corresponding #include: when the compiler sees the module import above, it loads a binary representation of the module and makes its API available to the application directly. Preprocessor definitions that precede the import declaration have no impact on the API provided... because the module itself was compiled as a separate, standalone module. Additionally, any linker flags required to use the module will automatically be provided when the module is imported. This semantic import model addresses many of the problems of the preprocessor inclusion model.

To enable modules, pass the command-line flag -fmodules aka CLANG_ENABLE_MODULES in Xcode- at compile time. As mentioned above.. this strategy obviates ANY and ALL LDFLAGS. As in, you can REMOVE any "OTHER_LDFLAGS" settings, as well as any "Linking" phases..

enter image description here

I find compile / launch times to "feel" much snappier (or possibly, there's just less of a lag while "linking"?).. and also, provides a great opportunity to purge the now extraneous Project-Prefix.pch file, and corresponding build settings, GCC_INCREASE_PRECOMPILED_HEADER_SHARING, GCC_PRECOMPILE_PREFIX_HEADER, and GCC_PREFIX_HEADER, etc.

Also, while not well-documented… You can create module.maps for your own frameworks and include them in the same convenient fashion. You can take a look at my ObjC-Clang-Modules github repo for some examples of how to implement such miracles.


#include + guard == #import

#include guardWiki - macro guard, header guard or file guard prevents to double include a header by a preprocessor that can slow down a build time

The next step is

.pch[About] => @import[About]

[#import in .h or .m]


I agree with Jason.

I got caught out doing this:

#import <sys/time.h>  // to use gettimeofday() function
#import <time.h>      // to use time() function

For GNU gcc, it kept complaining that time() function was not defined.

So then I changed #import to #include and all went ok.

Reason:

You #import <sys/time.h>:
    <sys/time.h> includes only a part of <time.h> by using #defines

You #import <time.h>:
    No go. Even though only part of <time.h> was already included, as
    far as #import is concerned, that file is now already completely included.

Bottom line:

C/C++ headers traditionally includes parts of other include files.
So for C/C++ headers, use #include.
For objc/objc++ headers, use #import.


IF you #include a file two times in .h files than compiler will give error. But if you #import a file more than once compiler will ignore it.


I know this thread is old... but in "modern times".. there is a far superior "include strategy" via clang's @import modules - that is oft-overlooked..

Modules improve access to the API of software libraries by replacing the textual preprocessor inclusion model with a more robust, more efficient semantic model. From the user’s perspective, the code looks only slightly different, because one uses an import declaration rather than a #include preprocessor directive:

@import Darwin; // Like including all of /usr/include. @see /usr/include/module.map

or

@import Foundation;  //  Like #import <Foundation/Foundation.h>
@import ObjectiveC;  //  Like #import <objc/runtime.h>

However, this module import behaves quite differently from the corresponding #include: when the compiler sees the module import above, it loads a binary representation of the module and makes its API available to the application directly. Preprocessor definitions that precede the import declaration have no impact on the API provided... because the module itself was compiled as a separate, standalone module. Additionally, any linker flags required to use the module will automatically be provided when the module is imported. This semantic import model addresses many of the problems of the preprocessor inclusion model.

To enable modules, pass the command-line flag -fmodules aka CLANG_ENABLE_MODULES in Xcode- at compile time. As mentioned above.. this strategy obviates ANY and ALL LDFLAGS. As in, you can REMOVE any "OTHER_LDFLAGS" settings, as well as any "Linking" phases..

enter image description here

I find compile / launch times to "feel" much snappier (or possibly, there's just less of a lag while "linking"?).. and also, provides a great opportunity to purge the now extraneous Project-Prefix.pch file, and corresponding build settings, GCC_INCREASE_PRECOMPILED_HEADER_SHARING, GCC_PRECOMPILE_PREFIX_HEADER, and GCC_PREFIX_HEADER, etc.

Also, while not well-documented… You can create module.maps for your own frameworks and include them in the same convenient fashion. You can take a look at my ObjC-Clang-Modules github repo for some examples of how to implement such miracles.


#include works just like the C #include.

#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.

The bottom line is just use #import in Objective-C and don't worry if your headers wind up importing something more than once.


#include it used to get "things" from another file to the one the #include is used in. Ex:

in file: main.cpp

#include "otherfile.h"

// some stuff here using otherfile.h objects,
// functions or classes declared inside

Header guard is used on the top of each header file (*.h) to prevent including the same file more then once (if it happens you will get compile errors).

in file: otherfile.h

#ifndef OTHERFILE
#define OTHERFILE

// declare functions, classes or objects here

#endif

even if you put #include "otherfile.h" n time in your code, this inside it will not be redeclared.


#include works just like the C #include.

#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.

The bottom line is just use #import in Objective-C and don't worry if your headers wind up importing something more than once.


In may case I had a global variable in one of my .h files that was causing the problem, and I solved it by adding extern in front of it.


#include works just like the C #include.

#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.

The bottom line is just use #import in Objective-C and don't worry if your headers wind up importing something more than once.


If you are familiar with C++ and macros, then

#import "Class.h" 

is similar to

{
#pragma once

#include "class.h"
}

which means that your Class will be loaded only once when your app runs.


There seems to be a lot of confusion regarding the preprocessor.

What the compiler does when it sees a #include that it replaces that line with the contents of the included files, no questions asked.

So if you have a file a.h with this contents:

typedef int my_number;

and a file b.c with this content:

#include "a.h"
#include "a.h"

the file b.c will be translated by the preprocessor before compilation to

typedef int my_number;
typedef int my_number;

which will result in a compiler error, since the type my_number is defined twice. Even though the definition is the same this is not allowed by the C language.

Since a header often is used in more than one place include guards usually are used in C. This looks like this:

 #ifndef _a_h_included_
 #define _a_h_included_

 typedef int my_number;

 #endif

The file b.c still would have the whole contents of the header in it twice after being preprocessed. But the second instance would be ignored since the macro _a_h_included_ would already have been defined.

This works really well, but has two drawbacks. First of all the include guards have to be written, and the macro name has to be different in every header. And secondly the compiler has still to look for the header file and read it as often as it is included.

Objective-C has the #import preprocessor instruction (it also can be used for C and C++ code with some compilers and options). This does almost the same as #include, but it also notes internally which file has already been included. The #import line is only replaced by the contents of the named file for the first time it is encountered. Every time after that it is just ignored.


#include + guard == #import

#include guardWiki - macro guard, header guard or file guard prevents to double include a header by a preprocessor that can slow down a build time

The next step is

.pch[About] => @import[About]

[#import in .h or .m]


Examples related to objective-c

Adding a UISegmentedControl to UITableView Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Warp \ bend effect on a UIView? Use NSInteger as array index Detect if the device is iPhone X Linker Command failed with exit code 1 (use -v to see invocation), Xcode 8, Swift 3 ITSAppUsesNonExemptEncryption export compliance while internal testing? How to enable back/left swipe gesture in UINavigationController after setting leftBarButtonItem? Change status bar text color to light in iOS 9 with Objective-C

Examples related to import

Import functions from another js file. Javascript The difference between "require(x)" and "import x" pytest cannot import module while python can How to import an Excel file into SQL Server? When should I use curly braces for ES6 import? How to import a JSON file in ECMAScript 6? Python: Importing urllib.quote importing external ".txt" file in python beyond top level package error in relative import Reading tab-delimited file with Pandas - works on Windows, but not on Mac

Examples related to include

"Multiple definition", "first defined here" errors Warning: require_once(): http:// wrapper is disabled in the server configuration by allow_url_include=0 Include PHP file into HTML file Cannot open include file with Visual Studio How to make Apache serve index.php instead of index.html? Include php files when they are in different folders Already defined in .obj - no double inclusions What's the difference between including files with JSP include directive, JSP include action and using JSP Tag Files? What is the correct syntax of ng-include? Visual Studio can't 'see' my included header files