回答:
#importディレクティブは、#includeの改良バージョンとしてObjective-Cに追加されました。しかし、それが改善されるかどうかはまだ議論の問題です。#importにより、ファイルが一度だけインクルードされることが保証されるため、再帰的なインクルードで問題が発生することはありません。ただし、ほとんどのまともなヘッダーファイルはとにかくこれから自分自身を保護するため、実際にはそれほどメリットはありません。
基本的に、どちらを使用するかを決めるのはあなた次第です。(クラス定義などの)Objective-Cのヘッダーを#importし、必要な標準のCのものを#includeする傾向があります。たとえば、ソースファイルの1つは次のようになります。
#import <Foundation/Foundation.h>
#include <asl.h>
#include <mach/mach.h>
#ifndef myheader #define myheader
...ヘッダーコードが続きます...#endif
プリプロセッサに関しては多くの混乱があるようです。
コンパイラーが#include
その行をインクルードされたファイルの内容で置き換えることがわかったときに何をするか、質問はされません。
したがってa.h
、この内容のファイルがある場合:
typedef int my_number;
そしてb.c
この内容のファイル:
#include "a.h"
#include "a.h"
ファイルb.c
はコンパイル前にプリプロセッサによって変換されます
typedef int my_number;
typedef int my_number;
型my_number
が2回定義されているため、コンパイラエラーが発生します。定義は同じですが、これはC言語では許可されていません。
ヘッダーは複数の場所で使用されることが多いため、インクルードガードは通常Cで使用されます。これは次のようになります。
#ifndef _a_h_included_
#define _a_h_included_
typedef int my_number;
#endif
ファイルb.c
は、前処理された後も、ヘッダーの内容全体が2回残っています。ただし、マクロ_a_h_included_
はすでに定義されているため、2番目のインスタンスは無視されます。
これは非常にうまく機能しますが、2つの欠点があります。最初に、インクルードガードを記述する必要があります。また、マクロ名はヘッダーごとに異なる必要があります。次に、コンパイラーはヘッダーファイルを探して、含まれている回数だけ読み取る必要があります。
Objective-Cには#import
プリプロセッサー命令があります(一部のコンパイラーとオプションでCおよびC ++コードに使用することもできます)。これはとほぼ同じですが#include
、内部でどのファイルが既にインクルードされているかも記録します。この#import
行は、最初に見つかったときに、指定されたファイルの内容によってのみ置き換えられます。その後は毎回無視されます。
#include
秒を#import
sに変更すると、コンパイルとXCodeインテリセンスの応答性が大幅に向上します。(私はそれを想像しているとは思いません)
私はジェイソンに同意します。
私はこれをしていることに引っ掛かりました:
#import <sys/time.h> // to use gettimeofday() function
#import <time.h> // to use time() function
GNU gccの場合、time()関数が定義されていないことに文句を言い続けました。
それで、私は#importを#includeに変更し、すべてうまくいきました。
理由:
#import <sys / time.h>:
<sys / time.h>には、#definesを使用して<time.h>の一部のみが含まれます
あなた#import <time.h>:
行きません。<time.h>の一部だけがすでに含まれていても、
#importに関する限り、そのファイルはすでに完全に含まれています。
結論:
C / C ++ヘッダーには、従来、他のインクルードファイルの一部が含まれています。
したがって、C / C ++ヘッダーの場合は#includeを使用します。
objc / objc ++ヘッダーの場合、#importを使用します。
#include
Cと同じように動作し#include
ます。
#import
どのヘッダーが既に含まれているかを追跡し、コンパイル単位でヘッダーが複数回インポートされた場合は無視されます。これにより、ヘッダーガードを使用する必要がなくなります。
一番下の行は#import
Objective-Cで使用するだけであり、ヘッダーが何かを何度もインポートすることになっても心配しないでください。
私はこのスレッドが古いことを知っています...しかし「現代」では.. clangの@import
モジュールを介したはるかに優れた「インクルード戦略」があります -見過ごされがちです...
モジュールは、テキストのプリプロセッサ包含モデルをより堅牢で効率的なセマンティックモデルに置き換えることにより、ソフトウェアライブラリのAPIへのアクセスを改善します。#includeプリプロセッサディレクティブではなくインポート宣言を使用するため、ユーザーの観点から見ると、コードはわずかに異なっているように見えます。
@import Darwin; // Like including all of /usr/include. @see /usr/include/module.map
または
@import Foundation; // Like #import <Foundation/Foundation.h>
@import ObjectiveC; // Like #import <objc/runtime.h>
ただし、このモジュールインポートの動作は、対応する#includeとは大きく異なります。コンパイラが上記のモジュールインポートを検出すると、モジュールのバイナリ表現を読み込み、そのAPIをアプリケーションで直接利用できるようにします。インポート宣言の前にあるプリプロセッサ定義は、提供されるAPIに影響を与えません...モジュール自体が独立したスタンドアロンモジュールとしてコンパイルされているためです。さらに、モジュールのインポート時に、モジュールの使用に必要なリンカーフラグが自動的に提供されます。このセマンティックインポートモデルは、プリプロセッサ包含モデルの問題の多くに対処します。
モジュールを有効にするために、コマンド・ライン・フラグを渡す-fmodules
別名CLANG_ENABLE_MODULES
でXcode
コンパイル時に- 。上記のように、この戦略はANYおよびALLを取り除きLDFLAGS
ます。同様に、「OTHER_LDFLAGS」設定や「リンク」フェーズを削除できます。
私はコンパイル/起動時間をより迅速に「感じる」(または、おそらく「リンク」中のラグが少ないだけです)と思います。また、今では無関係なProject-Prefix.pchファイルをパージする絶好の機会を提供します。ビルド設定に対応する、GCC_INCREASE_PRECOMPILED_HEADER_SHARING
、GCC_PRECOMPILE_PREFIX_HEADER
、およびGCC_PREFIX_HEADER
、など
また、十分に文書化されていませんがmodule.map
、独自のフレームワーク用のを作成して、同じ便利な方法でそれらを含めることができます。 このような奇跡を実装する方法の例については、私のObjC-Clang-Modules githubリポジトリをご覧ください。
C ++とマクロに精通している場合は、
#import "Class.h"
と類似しています
{
#pragma once
#include "class.h"
}
つまり、アプリの実行時にクラスが1回だけ読み込まれます。
#pragma once
インクルードを実行するファイルではなく、インクルードファイルに配置されます。そのため-1。
.hファイルにファイルを2回#includeすると、コンパイラーはエラーを出します。しかし、ファイルを複数回インポートすると、コンパイラはそれを無視します。
#include
同じファイルを2回使用してもエラーにはなりません。
#include
は単にコピーアンドペーストのメカニズムです。#include
"Xマクロ"のように、インクルードガードなしで意図的に複数回使用されています。
#include
ある種のテンプレートを実装するために使用されるCコードを見てきました。彼らはを行い、#define
ヘッダーを含め、#undef
dをやり直し#define
、同じヘッダーをもう一度含めました。これにより、defineの値が異なるため、コードがパラメーター化され、有効になり、2回インクルードされました。したがって#include
、を使用することには利点がありますが、C ++やObjCなどの最新の言語を使用している場合は、通常これは必要ありません。
#include
別のファイルから#include
使用されているファイルに「もの」を取得するために使用されていました。例:
ファイル内:main.cpp
#include "otherfile.h"
// some stuff here using otherfile.h objects,
// functions or classes declared inside
ヘッダーガードは各ヘッダーファイル(* .h)の上部で使用され、同じファイルが複数回インクルードされないようにします(この場合、コンパイルエラーが発生します)。
ファイル内:otherfile.h
#ifndef OTHERFILE
#define OTHERFILE
// declare functions, classes or objects here
#endif
#include
"otherfile.h"をコードにn回入れても、その内部は再宣言されません。