Директива #import была добавлена в Objective-C как улучшенная версия #include. Однако все же вопрос о том, улучшился он или нет, все еще остается предметом дискуссий #import гарантирует, что файл будет включен только один раз, чтобы у вас никогда не возникало проблем с рекурсивными включениями. Тем не менее, большинство приличных заголовочных файлов защищают себя от этого в любом случае, так что это не так уж много пользы.
По сути, вам решать, что вы хотите использовать. Я стремлюсь # импортировать заголовки для объектов Objective-C (таких как определения классов и тому подобное) и #include стандартные вещи C, которые мне нужны. Например, один из моих исходных файлов может выглядеть так:
#import <Foundation/Foundation.h>
#include <asl.h>
#include <mach/mach.h>
#ifndef myheader #define myheader
... сопровождается кодом заголовка ...#endif
Кажется, есть много путаницы в отношении препроцессора.
Что делает компилятор, когда он видит,
#include
что он заменяет эту строку содержимым включенных файлов, без вопросов.Итак, если у вас есть файл
a.h
с этим содержимым:и файл
b.c
с этим содержанием:файл
b.c
будет переведен препроцессором перед компиляцией вчто приведет к ошибке компилятора, так как тип
my_number
определяется дважды. Хотя определение одно и то же, это не допускается языком Си.Поскольку заголовок часто используется более чем в одном месте , в C обычно используются защитные элементы. Это выглядит так:
Файл
b.c
все равно будет содержать все содержимое заголовка дважды после предварительной обработки. Но второй экземпляр будет игнорироваться, так как макрос_a_h_included_
уже будет определен.Это работает очень хорошо, но имеет два недостатка. Прежде всего, должны быть включены защитные элементы, а имя макроса должно быть разным в каждом заголовке. И, во-вторых, компилятор все еще должен искать заголовочный файл и читать его так часто, как он включен.
Objective-C имеет
#import
инструкцию препроцессора (ее также можно использовать для кода C и C ++ с некоторыми компиляторами и опциями). Это делает почти то же самое#include
, но также отмечает, какой файл уже был включен.#import
Линия заменяется только содержимое указанного файла в первый раз она встречается. Каждый раз после этого это просто игнорируется.источник
#include
с на#import
s в заголовочном файле шаблона с 7000 строк заметно улучшается производительность компиляции и отзывчивость XCode intellisense. (Я не думаю, что я себе это представляю)Я согласен с Джейсоном.
Я был пойман, делая это:
Для GNU gcc он продолжал жаловаться, что функция time () не была определена.
Затем я изменил #import на #include и все прошло нормально.
Причина:
Вы #import <sys / time.h>:
<sys / time.h> включаете только часть <time.h>, используя #defines
Вы #import <time.h>:
нет. Даже если была включена только часть <time.h>, что
касается #import, этот файл уже полностью включен.
Нижняя граница:
Заголовки C / C ++ традиционно включают в себя части других включаемых файлов.
Так что для заголовков C / C ++ используйте #include.
Для заголовков objc / objc ++ используйте #import.
источник
#include
работает так же , как C#include
.#import
отслеживает, какие заголовки уже включены, и игнорируется, если заголовок импортирован более одного раза в блок компиляции. Это делает ненужным использование охранников заголовка.Суть в том, что вы просто используете
#import
Objective-C и не беспокойтесь, если ваши заголовки импортируют что-то более одного раза.источник
Я знаю, что эта ветка старая ... но в "современную эпоху" ... гораздо лучше "включить стратегию" через модули Clang
@import
- это часто упускается из виду ...или
Чтобы включить модули, передайте флаг командной строки
-fmodules
akaCLANG_ENABLE_MODULES
inXcode
- во время компиляции. Как упомянуто выше .. эта стратегия устраняет ЛЮБОЕ и ВСЕLDFLAGS
. Например, вы можете УДАЛИТЬ любые настройки «OTHER_LDFLAGS», а также любые фазы «Связывания».Я нахожу, что время компиляции / запуска «чувствует» намного быстрее (или, может быть, при «связывании» меньше задержки), а также предоставляет отличную возможность очистить теперь посторонний файл Project-Prefix.pch, и соответствующие параметры сборки,
GCC_INCREASE_PRECOMPILED_HEADER_SHARING
,GCC_PRECOMPILE_PREFIX_HEADER
, иGCC_PREFIX_HEADER
т.д.Кроме того, хотя они недостаточно хорошо документированы ... Вы можете создавать
module.map
s для своих собственных фреймворков и включать их таким же удобным способом. Вы можете взглянуть на мой репозиторий ObjC-Clang-Modules github для некоторых примеров того, как реализовать такие чудеса.источник
Если вы знакомы с C ++ и макросами, тогда
похоже на
Это означает, что ваш класс будет загружен только один раз при запуске приложения.
источник
#pragma once
помещается во включаемый файл, а не в файл, который выполняет включение. -1 за это.В некоторых случаях у меня была глобальная переменная в одном из моих
.h
файлов, которая вызывала проблему, и я решил ее, добавивextern
перед ней.источник
Если вы #include файл два раза в .h файлы, чем компилятор выдаст ошибку. Но если вы импортируете файл более одного раза, компилятор проигнорирует его.
источник
#include
один и тот же файл дважды не приводит к ошибке.#include
это просто механизм копирования и вставки. Преднамеренное использование#include
более одного раза без включения охранников, например, «X macro».#include
для реализации своего рода шаблонов. Они сделали a#define
, включили заголовок,#undef
d и переделали#define
, включили тот же заголовок во второй раз. Это привело к тому, что код был параметризован, действителен и включен дважды, так как значение определения было другим. Таким образом, у использования есть свои преимущества#include
, но если вы используете современный язык, такой как C ++ или ObjC, вам это обычно не нужно.#include
раньше он получал «вещи» из другого файла в тот,#include
который используется. Пример:в файле: main.cpp
Защита заголовка используется в верхней части каждого заголовочного файла (* .h), чтобы предотвратить включение одного и того же файла более одного раза (если это произойдет, вы получите ошибки компиляции).
в файле: otherfile.h
даже если вы
#include
добавите в свой код файл «otherfile.h» n раз, он не будет переопределен.источник
#include guard
Wiki - защита от макросов, защита заголовков или защита файлов предотвращает двойное включение заголовкаpreprocessor
что может замедлить время сборкиСледующий шаг
.pch
[About] =>@import
[About][# импорт в
.h
или.m
]источник