@import vs #import - iOS 7

365

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

@import UIKit;

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

Теги:
import
ios7

5 ответов

779
Лучший ответ

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

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

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

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

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

Изображение 5422

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

Изображение 5423

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


Из слайдов WWDC:

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

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

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

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

@import iAd.ADBannerView;

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

  • 14
    @DaveDeLong & Klaas: Спасибо! Я должен признать, что ничего не знал о модулях, когда впервые ответил на это. Я пошел и посмотрел сессию 404, чтобы узнать ее. Презентация, которую провел Даг Грегор (парень из LLVM), была действительно хорошо сделана. Также есть обсуждение модулей C ++, где объясняются преимущества здесь: youtube.com/watch?v=4Xo9iH5VLQ0
  • 3
    @ Неван-- спасибо за ответ. Я просто хотел добавить, что модули пока не поддерживают сторонние и ваши собственные фреймворки.
Показать ещё 18 комментариев
38

Хороший ответ вы можете найти в книге 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 в коде вместе без каких-либо проблем.

  • 0
    В моем проекте (Xcode 6) нет опции, которую я впервые запустил в Xcode 4 для включения модулей. Можно ли как-нибудь добавить это вручную?
  • 0
    Цель сборки - iOS 6, думаю, это проблема
2

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

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

  • 0
    Да, у меня тоже есть эта проблема, но установка на НЕТ удаляет все предупреждения. Будет ли побочный эффект, когда я сделаю это?
2

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

1

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню