it-swarm.com.ru

@import vs #import - iOS 7

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

@import UIKit;

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

419
jamdaddy25

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

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

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

Модули предварительно созданы для большинства 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.

828
nevan king

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

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

#import "someFile.h"

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

#import <SomeLibrary/SomeFile.h>

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

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

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

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

#import <SomeLibrary/SomeFile.h>

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

@import SomeLibrary;

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

@import AwesomeLibrary.AwesomeObject;

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

44
gbk

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

3
RyanTCB

Похоже, что начиная с XCode 7.x появляется много предупреждений при включении модуля clang с помощью CLANG_ENABLE_MODULES

Взгляните на много предупреждений при сборке с Xcode 7 с сторонними библиотеками

2
loretoparisi

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

1
Julian Król