Каркас — это библиотека скомпилированного кода, который используется вашей программой.

Большинство каркасов, использующихся при разработке приложения для системы iOS, являются встроенными каркасами компании Apple. Во время выполнения программы эти каркасы уже являются частью системы, установленной на устройстве; они находятся в папке /System/Library/Frameworks, расположенной на устройстве, но увидеть их на устройствах iPhone или iPad невозможно, потому что в обычном режиме увидеть непосредственно файловую иерархию нельзя.

Ваш скомпилированный код также должен быть связан с этими каркасами во время сборки проекта на вашем компьютере. Для того чтобы это было возможно, папка System/Library/Frameworks с устройства iOS дублируется на компьютере в самой среде Xcode. Это продублированное подмножество системы, установленной на устройстве, называется пакетом SDK (software development kit — пакет инструментальных средств для разработки программного обеспечения). То, как используется пакет SDK, зависит от того, для какого устройства вы разрабатываете приложение.

Связывание — это процесс соединения вашего скомпилированного кода с необходимыми каркасами, несмотря на то, что во время сборки каркасы находятся в одном месте, а во время выполнения приложения — в другом.

 

Когда вы собираете ваш код для запуска на устройстве

Используется копия необходимых каркасов. Эта копия находится в папке System/ Library/Frameworks/ в пакете iPhone SDK, который хранится в папке Xcode.арр/ Contents/Developer/Platforms/iPhoneOS.platfоrm/Developer/SDKs/ iPhoneOS7.0.sdk.

 

Когда ваш код выполняется на устройстве

После запуска код ищет необходимые каркасы на устройстве в папке /System/ Library/Frameworks/.

 

Таким образом, каркасы являются частью искусного механизма Apple для инкорпорации кода в выполняемое приложение. Каркасы содержат все, что необходимо для работы приложений; совокупность этих элементов называется Cocoa. Этих элементов очень много. Ваше приложение может использовать мощь каркасов благодаря связи с ними. Ваш код работает так, будто каркас инкорпорирован в него. Даже если ваше приложение относительно маленькое, его каркасы могут быть огромными.

Связывание обеспечивает соединение скомпилированного кода с необходимыми каркасами, но для успеха этого недостаточно. Каркасы заполнены классами (например, NSString) и методами (например, uppercaseString), которые ваш код будет вызывать. Для того чтобы удовлетворить требования компилятора, каркасы делают то, что делает любая программа на языке С или Objective-C: они публикуют свой интерфейс в заголовочных файлах (. h), которые импортируются вашим кодом. Таким образом, например, ваш код может обратиться к классу NSString и вызвать функцию uppercaseString, потому что он импортирует заголовочный файл NSString.h. На самом деле ваш код импортирует заголовочный файл UIKit. h, который в свою очередь импортирует файл Foundation. h, который в свою очередь импортирует файл NSString. h. Это можно увидеть в первой строке вашего кода:

#import <UIKit/UIKit.h>

(Импорт файлов классов и его предназначение описан в примере 4.1.)

Таким образом, каркас представляет собой двухэтапный процесс.

 

Импорт заголовка каркаса

Эта информация необходима вашему коду для успешной компиляции. Ваш код импортирует заголовок каркаса с помощью директивы #import, либо непосредственно указывая заголовок каркаса, либо импортируя заголовок, который в свою очередь импортирует заголовок каркаса.

Связывание с каркасом

Скомпилированный исполняемый бинарный код должен быть связан с каркасами, которые будут использоваться во время выполнения приложения, на самом деле инкорпорируя скомпилированный код, образующий эти каркасы. После сборки код связывается со всеми необходимыми каркасами в соответствии со списком каркасов, заданном на фазе сборки цели Link Binary With Libraries.

По умолчанию шаблон уже связал три каркаса с вашим целевым приложением. Он сделал это, перечислив их на фазе сборки Link Binary With Libraries (затем каркасы появляются также в окне навигатора проекта в группе Frameworks, и с помощью этого списка можно просматривать и проверять заголовочные файлы).

 

Каркас UIKi t

Классы Cocoa, специализированные для системы iOS, имена которых начинаются с букв “UI,” являются частью каркаса UIKit. Каркас UIKit импортируется (<UIKit/UIKit.h>) в предварительно скомпилированный заголовочный файл и в заголовочные файлы классов, образующих шаблон приложения, такие как AppDelegate. h, а также в файлы классов, которые пишете вы.

 

Каркас Foundation

Многие классы каркаса Cocoa, такие как NSString и NSArray, а также другие файлы, имена которых начинаются с букв “NS”, являются частью каркаса Foundation framework. Этот каркас импортируется в предварительно скомпилированный заголовочный файл, но делать это не обязательно, потому что многие заголовки, импортируемые файлом UIKit. h, импортируют каркас Foundation (<Foundation/ Foundation.h>). В свою очередь, файл Foundation.h включает заголовки каркаса Core Foundation (<CoreFoundation/CoreFoundation.h>) и загружает каркас Core Foundation как вложенный каркас; таким образом, нет необходимости явно импортировать Core Foundation (наполненный функциями и типами указателей, имена которых начинаются с букв “CF”, например CFStringRef) или связывать с ним свой код.

 

Каркас Core Graphics

Каркас Core Graphics определяет множество структур и функций, связанных с рисованием, имена которых начинаются с букв “CG”. Он импортируется многими заголовками каркаса UIKit, поэтому необязательно импортировать его явно.

Система iOS имеет около пятидесяти каркасов, но шаблоны не импортируют их в ваш код и не связывают с вашей целью. Это объясняется тем, что дополнительные каркасы означают дополнительную работу как для компиляции, так и для запуска приложения. Следовательно, для того чтобы использовать эти дополнительные каркасы, вы должны выполнить оба этапа: импортировать заголовки каркасов там, где это необходимо, и связать ваш код с самими каркасами. Этот двухэтапный процесс довольно неудобен, но если вы пропустите один из этапов, то ничего не получится.

Например, допустим, что нас интересует каркас Address Book и мы редко используем его в нашем приложении. Тогда в нашем коде мы создадим объект

 

ABNewPersonViewController:ABNewPersonViewController* ab =

[ABNewPersonViewController new];

В следующий раз, кода мы будем собирать приложение, компилятор выдаст сообщение о том, что ABNewPersonViewController — необъявленный идентификатор. Тогда мы поймем, что нужно импортировать заголовок каркаса. Пара букв, с которых начинается имя ABNewPersonViewController, может служить подсказкой для поиска дополнительного каркаса; оно начинается не с букв “NS”, “UI” или “CG”. В документации к классу ABNewPersonViewController сказано, что он принадлежит каркасу AddressBookUI. Вы можете догадаться (и правильно), что в начале файла реализации следует поместить директиву импортирования каркаса:

#import <AddressBookUI/AddressBookUI.h>

Это позволяет предотвратить предупреждения компилятора, но код собран не будет. На этот раз мы получим сообщение об ошибке на этапе редактирования связей “Symbol (s) not found”, связанное с именем _OBJC_CLASS_$_ABNewPersonViewController. Это загадочное сообщение просто означает, что мы забыли о втором этапе: мы должны связать нашу цель с каркасом AddressBookUI. framework.

Для того чтобы связать цель с каркасом, необходимо отредактировать цель, щелкнуть на пункте General в верхней части редактора и прокрутить раздел Linked Frameworks and Libraries. (Эту же информацию можно получить, щелкнув на пункте Build Phases в верхней части редактора и открыв фазу сборки Link Binary With Libraries.) Щелкните на кнопке Plus, расположенной слева непосредственно под списком каркасов. Появляется диалоговое окно, в котором перечисляются существующие каркасы, являющиеся частью активного пакета SDK. Выберите каркас AddressBookUI. framework и щелкните на кнопке Add. Каркас AddressBookUI добавляется в фазу сборки Link Binary With Libraries. (Она появляется в навигаторе проекта.) Теперь можно собирать (и выполнять) приложение.

Начиная с версий Xcode 5 и LLVM 5.0, можно упростить подключение дополнительных каркасом с помощью модулей. Использование модулей регулируется настройкой сборки Enable Modules (С and Objective-C). По умолчанию этот параметр равен Yes для новых проектов, созданных из шаблонов приложения.

Модули — это кешированная информация, хранящаяся на компьютере в папке Library/Developer/Xcode/DerivedData/ModuleCache. Когда вы собираете приложение, импортирующее заголовок каркаса, а информация об этом каркасе не кеширована в модуле, она моментально кешируется в модуле. Перечислим преимущества использования модулей.

 

После предварительной компиляции получается код меньшего размера

После выполнения предварительной компиляции все, что было импортировано, буквально копируется в ваш код. Заголовки каркаса UIKit вместе с заголовками, которые они импортируют, состоят из более чем 30 ООО строк кода. Это значит, что для компиляции любого файла . m компилятор должен работать с файлом, который на 30 ООО строк длиннее, чем ваша программа. Однако, используя модули, мы оставляем информацию об импортируемом заголовке внутри модуля, и длина кода в результате предварительной компиляции увеличивается незначительно. Это также может ускорить процесс компиляции.

 

Более простые и короткие директивы импорта

Импортирование заголовка может оказаться неудобным. Имя заголовка должно быть в угловых скобках, причем нужно указать не только имя каркаса (которое фактически является именем папки), но и имя заголовочного файла.

#import <AddressBookUI/AddressBookUI.h>

С помощью модулей вместо директивы #import можно использовать новую директиву 0import (перед новой директивой import стоит символ а не #), в которой достаточно указать лишь имя каркаса и точку с запятой.

@import AddressBookUI;

Более того, директивы #import автоматически конвертируются в директивы @imports, поэтому программист может писать как угодно, и существующие программы, в которых используются директивы #import, будут работать по-прежнему, но используя преимущества модулей.

 

Авто-связывание

Использование каркасов — двух-этапный процесс. Необходимо не только импортировать заголовок, но и связать код с каркасом. Модули позволяют пропустить второй этап. Это удобство можно использовать или не использовать (с помощью настройки сборки Link Frameworks Automatically), но по умолчанию оно используется. В результате, если код импортирует заголовок каркаса, ваша цель не обязательно будет связана с каркасом. Связывание будет выполняться автоматически во время процесса сборки.

 

Модули — это искусный и удобный механизм, но у них есть и недостатки по сравнению со старым способом явного импортирования и связывания. Например, когда каркас явно связывается с вашим проектом, вы знаете его, потому что он перечислен в фазе сборки Link Binary With Libraries и в навигаторе проекта. Применяя модули, вы не знаете, какие каркасы используете; у вас нет списка каркасов, которые автоматически связываются с кодом.

Более того, поскольку автоматически связываемые каркасы не перечислены в навигаторе проекта, их заголовки невозможно искать и просматривать в навигаторе проекта (в то время как явно связываемые каркасы это допускали с помощью области видимости “within workspace and frameworks” (“в рабочем пространстве и каркасах”)).

К счастью, если вы не воспользуетесь этой возможностью, то сможете связаться с каркасом вручную и включить его в список каркасов в навигаторе проекта, даже если он связывается автоматически.


 

 

 

Добавить комментарий