Spec-Zone .ru
спецификации, руководства, описания, API

Библиотека разработчика XCode

Разработчик

Используя Swift с какао и Objective C

iBook
На этой странице

Взаимодействие с APIs C

Как часть его функциональной совместимости с Objective C, Swift поддерживает совместимость со многими типами языка C и функциями. Swift также предоставляет методам работы общие конструкции C и образцы, в случае, если Ваш код требует его.

Типы примитивов

Swift обеспечивает эквиваленты примитивных целых типов C — например, char, int, float, и double. Однако нет никакого неявного преобразования между этими типами и базовыми целыми типами Swift, такой как Int. Поэтому используйте эти типы, если Ваш код в частности требует их, но использовать Int по мере возможности иначе.

C тип

Тип Swift

bool

CBool

char, signed char

CChar

unsigned char

CUnsignedChar

short

CShort

unsigned short

CUnsignedShort

int

CInt

unsigned int

CUnsignedInt

long

CLong

unsigned long

CUnsignedLong

long long

CLongLong

unsigned long long

CUnsignedLongLong

wchar_t

CWideChar

char16_t

CChar16

char32_t

CChar32

float

CFloat

double

CDouble

Перечисления

Swift импортирует как перечисление Swift любое перечисление C-стиля, отмеченное с NS_ENUM макрос. Это означает, что префиксы к именам перечислимой величины являются усеченными, когда они импортируются в Swift, определяются ли они в системных платформах или в пользовательском коде. Например, посмотрите это перечисление Objective C:

Objective C

  • typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
  • UITableViewCellStyleDefault,
  • UITableViewCellStyleValue1,
  • UITableViewCellStyleValue2,
  • UITableViewCellStyleSubtitle
  • };

В Swift это импортируется как это:

Swift

  • enum UITableViewCellStyle: Int {
  • case Default
  • case Value1
  • case Value2
  • case Subtitle
  • }

Когда Вы обратитесь к перечислимой величине, используйте имя значения с ведущей точкой (.).

Swift

  • let cellStyle: UITableViewCellStyle = .Default

Swift также импортирует опции, отмеченные с NS_OPTIONS макрос. Принимая во внимание, что опции ведут себя так же к импортированным перечислениям, опции могут также поддерживать некоторые битовые операции, такой как &, |, и ~.

В Objective C Вы представляете пустой набор опции с постоянным нулем (0). В Swift использовать nil представлять отсутствие любых опций. Например:

Swift

  • let myString = myData.base64EncodedStringWithOptions(nil)

Указатели

Каждый раз, когда возможно, Swift избегает предоставлять Вам прямой доступ к указателям. Существуют, однако, различные типы указателей, доступные для Вашего использования при необходимости в прямом доступе к памяти. Использование следующих таблиц Type как имя типа заполнителя для указания синтаксиса для отображений.

Для типов возврата, переменных и параметров, применяются следующие отображения:

C синтаксис

Синтаксис Swift

const Type *

UnsafePointer<Type>

Type *

UnsafeMutablePointer<Type>

Для типов классов применяются следующие отображения:

C синтаксис

Синтаксис Swift

Type * const *

UnsafePointer<Type>

Type * __strong *

UnsafeMutablePointer<Type>

Type **

AutoreleasingUnsafeMutablePointer<Type>

Постоянные указатели

Когда функция объявляется как берущий a UnsafePointer<Type> параметр, это может принять любое следующее:

  • nil, который передается как нулевой указатель

  • UnsafePointer<Type>, UnsafeMutablePointer<Type>, или AutoreleasingUnsafeMutablePointer<Type> значение, преобразовывающееся в UnsafePointer<Type> при необходимости

  • В - выражение, операнд которого является lvalue типа Type, который передается как адрес lvalue

  • A [Type] значение, передающееся как указатель на запуск массива и расширяющееся до времени жизни на время вызова

Если Вы объявили функцию как этот:

Swift

  • func takesAPointer(x: UnsafePointer<Float>) { /*...*/ }

Можно вызвать его любым из следующих способов:

Swift

  • var x: Float = 0.0
  • var p: UnsafePointer<Float> = nil
  • takesAPointer(nil)
  • takesAPointer(p)
  • takesAPointer(&x)
  • takesAPointer([1.0, 2.0, 3.0])

Когда функция объявляется как берущий a UnsafePointer<Void> параметр, это может принять те же операнды как UnsafePointer<Type> для любого типа Type.

Если Вы объявили функцию как этот:

Swift

  • func takesAVoidPointer(x: UnsafePointer<Void>) { /* ... */ }

Можно вызвать его любым из следующих способов:

Swift

  • var x: Float = 0.0, y: Int = 0
  • var p: UnsafePointer<Float> = nil, q: UnsafePointer<Int> = nil
  • takesAVoidPointer(nil)
  • takesAVoidPointer(p)
  • takesAVoidPointer(q)
  • takesAVoidPointer(&x)
  • takesAVoidPointer(&y)
  • takesAVoidPointer([1.0, 2.0, 3.0] as [Float])
  • let intArray = [1, 2, 3]
  • takesAVoidPointer(intArray)

Непостоянные указатели

Когда функция объявляется как взятие UnsafeMutablePointer<Type> параметр, это может принять любое следующее:

  • nil, который передается как нулевой указатель

  • UnsafeMutablePointer<Type> значение

  • В - выражение, операнд которого является сохраненным lvalue типа Type, который передается как адрес lvalue

  • В - [Type] значение, передающееся как указатель на запуск массива и расширяющееся до времени жизни на время вызова

Если Вы объявили функцию как этот:

Swift

  • func takesAMutablePointer(x: UnsafeMutablePointer<Float>) { /*...*/ }

Можно вызвать его любым из следующих способов:

Swift

  • var x: Float = 0.0
  • var p: UnsafeMutablePointer<Float> = nil
  • var a: [Float] = [1.0, 2.0, 3.0]
  • takesAMutablePointer(nil)
  • takesAMutablePointer(p)
  • takesAMutablePointer(&x)
  • takesAMutablePointer(&a)

Когда функция объявляется как взятие UnsafeMutablePointer<Void> параметр, это может принять те же операнды как UnsafeMutablePointer<Type> для любого типа Type.

Если Вы объявили функцию как этот:

Swift

  • func takesAMutableVoidPointer(x: UnsafeMutablePointer<Void>) { /* ... */ }

Можно вызвать его любым из следующих способов:

Swift

  • var x: Float = 0.0, y: Int = 0
  • var p: UnsafeMutablePointer<Float> = nil, q: UnsafeMutablePointer<Int> = nil
  • var a: [Float] = [1.0, 2.0, 3.0], b: [Int] = [1, 2, 3]
  • takesAMutableVoidPointer(nil)
  • takesAMutableVoidPointer(p)
  • takesAMutableVoidPointer(q)
  • takesAMutableVoidPointer(&x)
  • takesAMutableVoidPointer(&y)
  • takesAMutableVoidPointer(&a)
  • takesAMutableVoidPointer(&b)

Автовыпуск указателей

Когда функция объявляется как взятие AutoreleasingUnsafeMutablePointer<Type>, это может принять любое следующее:

  • nil, который передается как нулевой указатель

  • AutoreleasingUnsafeMutablePointer<Type> значение

  • В - выражение, операнд которого примитивно скопирован во временный буфер невладения. Адрес того буфера передается вызываемому, и по возврату, значение в буфере загружается, сохраняется и повторно присваивается в операнд.

Обратите внимание на то, что этот список не включает массивы.

Если Вы объявили функцию как этот:

Swift

  • func takesAnAutoreleasingPointer(x: AutoreleasingUnsafeMutablePointer<NSDate?>) { /* ... */ }

Можно вызвать его любым из следующих способов:

Swift

  • var x: NSDate? = nil
  • var p: AutoreleasingUnsafeMutablePointer<NSDate?> = nil
  • takesAnAutoreleasingPointer(nil)
  • takesAnAutoreleasingPointer(p)
  • takesAnAutoreleasingPointer(&x)

Типы, на которые указывают, не соединяются мостом. Например, NSString ** приезжает в Swift как AutoreleasingUnsafeMutablePointer<NSString?>, нет AutoreleasingUnsafeMutablePointer<String?>.

Указатели функции

C указатели функции импортируются в Swift как CFunctionPointer<Type>, где Type тип функции Swift. Например, указатель функции, имеющий тип int (*)(void) в C импортируется в Swift как CFunctionPointer<() -> Int32>.

Глобальные константы

Глобальные константы, определенные в C и исходных файлах Objective C, автоматически импортируются компилятором Swift как глобальные константы Swift.

Директивы препроцессору

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

Простые макросы

Где Вы обычно использовали #define директива для определения примитивной константы в C и Objective C в Swift Вы используете глобальную константу вместо этого. Например, постоянное определение #define FADE_ANIMATION_DURATION 0.35 может быть лучше выражен в Swift с let FADE_ANIMATION_DURATION = 0.35. Поскольку простые подобные константе макросы отображаются непосредственно на глобальные переменные Swift, компилятор автоматически импортирует простые макросы, определенные в исходных файлах Objective C и C.

Сложные макросы

Сложные макросы используются в C и Objective C, но не имеют никакого дубликата в Swift. Сложные макросы являются макросами, которые не определяют константы, включая заключенные в скобки, подобные функции макросы. Вы используете сложные макросы в C и Objective C, чтобы избежать проверяющих тип ограничений или избежать перепечатывать большие суммы шаблонного кода. Однако макросы могут сделать отладку и рефакторинг трудными. В Swift можно использовать функции и обобщения для достижения тех же результатов без любых компромиссов. Поэтому сложные макросы, которые находятся в C и исходных файлах Objective C, не сделаны доступными для Вашего Кода SWIFT.

Конфигурации сборки

Код SWIFT и код Objective C условно компилируются по-разному. Код SWIFT может быть условно скомпилирован на основе оценки конфигураций сборки. Конфигурации сборки включают литерал true и false значения, флаги командной строки и тестирующие платформу функции, перечисленные в таблице ниже. Можно указать, что командная строка отмечает использование -D <#flag#>.

Функция

Допустимые параметры

os()

OSX, iOS

arch()

x86_64, arm, arm64, i386

Простой оператор условной компиляции принимает следующую форму:

  • #if build configuration
  •     statements
  •     #else
  • statements
  • #endif

Операторы состоят из нуля или большего количества допустимых операторов Swift, которые могут включать выражения, операторы и операторы управления. Можно добавить дополнительные требования конфигурации сборки к оператору условной компиляции с && и || операторы, инвертируйте конфигурации сборки с ! оператор, и добавляет блоки условия с #elseif:

  • #if build configuration && !build configuration
  •     statements
  •     #elseif build configuration
  •     statements
  •     #else
  • statements
  • #endif

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