@import vs #import - iOS 7

Я играю с некоторыми из новых функций iOS 7 и работаю с некоторыми из эффектов изображения, как описано в видео WWDC "Реализация взаимодействия с пользовательским интерфейсом на iOS". Для создания эффекта размытия в исходном коде для сеанса UIImage был расширен через категорию, которая импортирует UIKit так:

@import UIKit;

Я думаю, что я видел что-то об этом в другом сеансовом видео, но мне трудно найти его. Я ищу любую справочную информацию о том, когда использовать это. Может ли он использоваться только с каркасами Apple? Являются ли преимущества использования этой директивы компилятора достаточной, чтобы я вернулся и обновил старый код?

Ответ 1

Это новая функция, называемая Модулями или "семантический импорт". Там больше информации в WWDC 2013 видео для сеанса 205 и 404. Это скорее улучшенная реализация предварительно скомпилированных заголовков. Вы можете использовать модули с любой из системных фреймворков в iOS 7 и Mavericks. Модули представляют собой упаковку вместе с исполняемым файлом фреймворка и его заголовками и рекламируются как более безопасные и эффективные, чем #import.

Одним из больших преимуществ использования @import является то, что вам не нужно добавлять фреймворк в параметры проекта, это делается автоматически. Это означает, что вы можете пропустить шаг, на который вы нажимаете кнопку "плюс", и искать фреймворк (золотой набор инструментов), а затем переместить его в группу "Рамки". Это избавит многих разработчиков от загадочных сообщений "Ошибка компоновщика".

На самом деле вам не нужно использовать ключевое слово @import.. Если вы входите в использование модулей, все директивы #import и #include сопоставляются для использования @import автоматически, Это означает, что вам не нужно менять исходный код (или исходный код библиотек, которые вы загружаете из других источников). Предположительно использование модулей также улучшает производительность сборки, особенно если вы не используете PCHs хорошо или если ваш проект имеет много небольших исходных файлов.

Модули предварительно построены для большинства фреймворков Apple (UIKit, MapKit, GameKit и т.д.). Вы можете использовать их с помощью созданных вами фреймворков: они создаются автоматически, если вы создаете среду Swift в Xcode, и вы можете вручную создать файл ".modulemap" самостоятельно для любая библиотека Apple или сторонних разработчиков.

Вы можете использовать завершение кода для просмотра списка доступных фреймворков:

enter image description here

Модули включены по умолчанию в новых проектах в Xcode 5. Чтобы включить их в более старый проект, зайдите в свои настройки сборки проекта, найдите "Модули" и установите "Включить модули" на "ДА". "Структуры ссылок" также должны быть "ДА":

Вы должны использовать Xcode 5 и iOS 7 или Mavericks SDK, но вы можете выпускать более старые ОС (скажем, iOS 4.3 или что-то еще). Модули не меняют способ создания кода или какого-либо исходного кода.


Из слайдов WWDC:

  • Импортирует полное семантическое описание структуры
  • Не нужно разбирать заголовки
  • Лучший способ импорта интерфейса фреймворков
  • Загружает двоичное представление
  • Более гибкие, чем предварительно скомпилированные заголовки.
  • Невосприимчивость к эффектам локальных макроопределений (например, #define readonly 0x01)
  • Включено для новых проектов по умолчанию

Чтобы явно использовать модули:

Замените #import <Cocoa/Cocoa.h> на @import Cocoa;

Вы также можете импортировать только один заголовок с помощью этой нотации:

@import iAd.ADBannerView;

Автокомпонент подмодулей для вас в Xcode.

Ответ 2

Хороший ответ вы можете найти в книге Learning Cocoa с Objective-C (ISBN: 978-1-491-90139-7)

Модули - это новое средство включения и компоновки файлов и библиотек в ваши проекты. Чтобы понять, как работают модули и какие преимущества у них есть, важно заглянуть в историю Objective-C и оператор #import Всякий раз, когда вы хотите включить файл для использования, вы обычно будете иметь код, который выглядит следующим образом:

#import "someFile.h"

Или в случае фреймворков:

#import <SomeLibrary/SomeFile.h>

Поскольку Objective-C является надмножеством языка программирования C, утверждение #import является незначительным уточнением в выражении Cs #include. Оператор #include очень прост; он копирует все, что находит во включенном файле, в ваш код во время компиляции. Иногда это может вызвать серьезные проблемы. Например, представьте, что у вас есть два файла заголовка: SomeFileA.h и SomeFileB.h; SomeFileA.h включает SomeFileB.h, а SomeFileB.h включает SomeFileA.h. Это создает петлю и может смущать coimpiler. Чтобы справиться с этим, программисты C должны писать защитные меры против этого типа событий.

При использовании #import вам не нужно беспокоиться об этой проблеме или писать защитники заголовка, чтобы избежать этого. Тем не менее, #import по-прежнему является просто прославленным действием копирования и вставки, что приводит к медленному времени компиляции среди множества других меньших, но все еще очень опасных проблем (таких как включенный файл, переопределяющий то, что вы указали в другом месте вашего собственного кода).

Модули - это попытка обойти это. Они больше не являются копией и вставкой в ​​исходный код, а представляют собой сериализованное представление включенных файлов, которые можно импортировать в исходный код только тогда, когда и где они нужны. Используя модули, код обычно компилируется быстрее и безопаснее, чем использование #include или #import.

Возврат к предыдущему примеру импорта фреймворка:

#import <SomeLibrary/SomeFile.h>

Чтобы импортировать эту библиотеку в качестве модуля, код будет изменен на:

@import SomeLibrary;

У этого есть дополнительный бонус Xcode, связывающий структуру SomeLibrary в проекте автоматически. Модули также позволяют включать только те компоненты, которые вам действительно нужны в ваш проект. Например, если вы хотите использовать компонент AwesomeObject в структуре AwesomeLibrary, обычно вам придется импортировать все, чтобы использовать только одну часть. Однако, используя модули, вы можете просто импортировать определенный объект, который хотите использовать:

@import AwesomeLibrary.AwesomeObject;

Для всех новых проектов, выполненных в Xcode 5, модули по умолчанию включены. Если вы хотите использовать модули в более старых проектах (и вы действительно должны), они должны быть включены в настройках построения проектов. Как только вы это сделаете, вы можете использовать оба оператора #import и @import в коде вместе без каких-либо проблем.

Ответ 3

В настоящее время он работает только для встроенных системных фреймворков. Если вы используете #import, так как apple все еще импортирует фреймворк UIKit в делетете приложения, он заменяется (если модули включены и распознаются как системная структура), и компилятор переназначает его как импорт модуля, а не импорт файлов заголовков в любом случае.  Таким образом, оставить #import будет таким же, как его конвертированный в импорт модуля, где это возможно, в любом случае

Ответ 5

Существует несколько преимуществ использования модулей. Вы можете использовать его только с каркасом Apple, если карта модуля не создана. @import немного похож на предварительную компиляцию файлов заголовков при добавлении в файл .pch, который является способом настройки приложения в процессе компиляции. Кроме того, вам не нужно добавлять библиотеки по-старому, используя @import, намного быстрее и эффективнее. Если вы все еще ищете хорошую ссылку, я настоятельно рекомендую вам читать эту статью.

Ответ 6

модуль[Structure] предлагает лучший способ работы с системными платформами и библиотеками, заменив механизм включения текста препроцессора тем, что Clang называет семантическим импортом. Для импорта модуля вы используете декларацию @import вместо директив препроцессора #include или #import

Когда компилятор видит импорт модуля @import, он загружает автономную версию precompiled двоичного файла. Это также автоматически заботится о связывании с модулем, означающим, что вам больше не нужно вручную добавлять фреймворк в Xcode. Поскольку модуль скомпилирован только один раз, больше нет никаких преимуществ включать заголовок фреймворка в prefix.pch. В результате настройка сборки заголовка префикса префикса теперь по умолчанию имеет значение NO в XCode.

@import решает следующие проблемы:

  • Импортирует полное семантическое описание фреймворка
  • Не нужно разбирать заголовки
  • Загружает двоичное представление
  • Более гибкий, чем предварительно скомпилированные заголовки .pch [About]
  • Нет необходимости поддерживать ваши файлы .pch

Директивы #import и #include автоматически преобразуются в @import за кулисами, что дает вам преимущество модулей без какой-либо работы.

Когда вы создаете свой собственный framework, XCode генерирует карту модулей, которая включает в себя umbrella header[About]

Когда вы создаете свой собственный library с использованием Objective-C, вам нужно будет создать собственную карту модуля (.modulemap) и убедиться, что ее содержимое обновлено. [Create a library] [setup modulemap] [Custom modulemap]

#mport против #include

Подробнее здесь, здесь