Работа с типами данных какао
Как часть его функциональной совместимости с Objective C, Swift предлагает удобные и эффективные методы работы с типами данных Какао.
Swift автоматически преобразовывает некоторые типы Objective C в типы Swift и некоторые типы Swift к типам Objective C. Существует также много типов данных в Swift и Objective C, который может использоваться взаимозаменяемо. Типы данных, которые конвертируемы или могут использоваться взаимозаменяемо, упоминаются как соединенные мостом типы данных. Например, в Коде SWIFT, можно передать Array
оцените методу, ожидая NSArray
объект. Можно также бросить между соединенным мостом типом и его дубликатом. Когда Вы бросаете между соединенными мостом типами с as
— или путем явного обеспечения типа постоянных или переменных — Swift соединяет тип данных мостом.
Swift также обеспечивает удобное наложение для взаимодействия через интерфейс с типами данных Основы, позволяя Вам работать с ними использующий синтаксис, чувствующий себя естественным и объединенным с остальной частью языка Swift.
Строки
Swift автоматически образует мост между String
введите и NSString
класс. Это означает, что где угодно Вы используете NSString
объект, можно использовать Swift String
введите вместо этого и получите выгоду от обоих типов — String
интерполяция типа и разработанный Swift APIs и NSString
широкая функциональность класса. Поэтому Вы никогда не должны почти должны быть использовать NSString
классифицируйте непосредственно в Вашем собственном коде. Фактически, когда Swift импортирует Objective C APIs, это заменяет весь из NSString
типы с String
типы. Когда Ваш код Objective C использует класс Swift, средство импорта заменяет весь из String
типы с NSString
в импортированном API.
Для включения строкового образования моста просто импортируйте Основу. Например, можно получить доступ capitalizedString
— свойство на NSString
класс — на строке Swift и Swift автоматически соединяет Swift мостом String
к NSString
возразите и получает доступ к свойству. Свойство даже возвращает Swift String
введите, потому что это было преобразовано во время импорта.
Swift
import Foundation
let greeting = "hello, world!"
let capitalizedGreeting = greeting.capitalizedString
// capitalizedGreeting: String = Hello, World!
Если действительно необходимо использовать NSString
объект, можно преобразовать его в Swift String
значение путем кастинга его. String
тип может всегда преобразовываться из NSString
возразите против Swift String
значение, таким образом, нет никакой потребности использовать дополнительную версию оператора преобразования типа (as?
). Можно также создать NSString
объект от строкового литерала путем явного ввода константы или переменный.
Swift
import Foundation
let myString: NSString = "123"
if let integerValue = (myString as String).toInt() {
println("\(myString) is the integer \(integerValue)")
}
Локализация
В Objective C Вы обычно использовали NSLocalizedString
семья макросов для локализации строк. Этот набор макросов включает NSLocalizedString
, NSLocalizedStringFromTable
, NSLocalizedStringFromTableInBundle
, и NSLocalizedStringWithDefaultValue
. В Swift можно использовать единственную функцию, обеспечивающую ту же функциональность как весь набор NSLocalizedString
макросы —NSLocalizedString(key:tableName:bundle:value:comment:)
. NSLocalizedString
функция обеспечивает значения по умолчанию для tableName
, bundle
, и value
параметры. Используйте его, как Вы использовали бы макрос, который это заменяет.
Числа
Swift автоматически соединяет определенные собственные типы числа мостом, такой как Int
и Float
, к NSNumber
. Это образование моста позволяет Вам создать NSNumber
от одного из этих типов:
Swift
let n = 42
let m: NSNumber = n
Это также позволяет Вам передавать значение типа Int
, например, к параметру, ожидающему NSNumber
. Обратите внимание на то, что, потому что NSNumber
может содержать множество различных типов, Вы не можете передать его чему-то, ожидая Int
значение.
Все следующие типы автоматически соединяются мостом к NSNumber
:
Int
UInt
Float
Double
Bool
Классы набора
Мосты Swift NSArray
, NSDictionary
, и NSSet
к Array
, Dictionary
, и Set
, соответственно. Это означает, что можно использовать в своих интересах мощные алгоритмы Swift и естественный синтаксис для работы с наборами — и использовать Основу и типы набора Swift взаимозаменяемо.
Массивы
Swift образует мост между Array
введите и NSArray
класс. Когда Вы образуете мост от NSArray
возразите против массива Swift, полученный массив имеет тип [AnyObject]
. Объект AnyObject
совместимый, если это - экземпляр Objective C или класса Swift, или если объект может быть соединен мостом одному. Можно соединить любого мостом NSArray
возразите против массива Swift, потому что все объекты Objective C AnyObject
совместимый. Поскольку все NSArray
объекты могут быть соединены мостом к массивам Swift, компилятор Swift заменяет NSArray
класс с [AnyObject]
когда это импортирует Objective C APIs.
После образования моста NSArray
возразите против массива Swift, Вы можете также нисходящий массив к более определенному типу. В отличие от кастинга от NSArray
класс [AnyObject]
введите, downcasting от AnyObject
к более определенному типу, как гарантируют, не успешно выполнится. Компилятор не может знать наверняка до времени выполнения, что все элементы в массиве могут быть downcasted к типу, который Вы указали. В результате Вы используете условного оператора преобразования типа as?
к нисходящему от [AnyObject]
к [SomeType]
, или безусловный оператор преобразования типа as!
когда Вы будете уверены, что успешно выполнится нисходящее. Например, если Вы знаете, что массив Swift содержит только экземпляры NSView
класс (или подкласс NSView
класс), Вы можете нисходящий массив AnyObject
введите элементы к массиву NSView
объекты. Если какой-либо элемент в массиве Swift не фактически a NSView
объект во время выполнения, возвраты броска nil
.
Swift
let swiftArray = foundationArray as [AnyObject]
if let downcastedSwiftArray = swiftArray as? [NSView] {
// downcastedSwiftArray contains only NSView objects
}
Вы можете также нисходящий непосредственно от NSArray
возразите против массива Swift определенного типа в для цикла:
Swift
for aView in foundationArray as! [NSView] {
// aView is of type UIView
}
Когда Вы образуете мост от массива Swift до NSArray
объект, элементы в массиве Swift должны быть AnyObject
совместимый. Например, массив Swift типа [Int]
содержит Int
элементы структуры. Int
тип не является экземпляром класса, но потому что Int
введите мосты к NSNumber
класс, Int
тип AnyObject
совместимый. Поэтому можно соединить массив Swift мостом типа [Int]
к NSArray
объект. Если элемент в массиве Swift не AnyObject
когда Вы образуете мост к, совместимый, ошибка периода выполнения происходит NSArray
объект.
Можно также создать NSArray
возразите непосредственно от литерала массивов Swift, соблюдя те же правила образования моста, обрисованные в общих чертах выше. Когда Вы явно вводите константу или переменный как NSArray
возразите и присвойте его литерал массивов, Swift создает NSArray
объект вместо массива Swift.
Swift
let schoolSupplies: NSArray = ["Pencil", "Eraser", "Notebook"]
// schoolSupplies is an NSArray object containing NSString objects
В примере выше, литерал массивов Swift содержит три String
литералы. Поскольку String
введите мосты к NSString
класс, литерал массивов соединяется мостом к NSArray
возразите и присвоение на schoolSupplies
успешно выполняется.
При использовании класса Swift или протокола в коде Objective C средство импорта заменяет все массивы Swift любого типа в импортированном API с NSArray
. Если Вы передаете NSArray
возразите против Swift API, ожидающего, что элементы будут иметь другой тип, ошибка периода выполнения происходит. Если Swift API возвращает массив Swift, который не может быть соединен мостом к NSArray
, ошибка периода выполнения происходит.
Словари
В дополнение к массивам Swift также автоматически образует мост между Dictionary
введите и NSDictionary
класс. Когда Вы образуете мост от NSDictionary
возразите против словаря Swift, получающийся словарь имеет тип [NSObject: AnyObject]
. Можно соединить любого мостом NSDictionary
возразите против словаря Swift, потому что все объекты Objective C AnyObject
совместимый. Вспомните, что объект AnyObject
совместимый, если это - экземпляр Objective C или класса Swift, или если это может быть соединено мостом одному. Все NSDictionary
объекты могут быть соединены мостом к словарям Swift, таким образом, компилятор Swift заменяет NSDictionary
класс с [NSObject: AnyObject]
когда это импортирует Objective C APIs. Аналогично, когда Вы используете класс Swift или протокол в коде Objective C, Objective C перекарт средства импорта совместимые словари Swift как NSDictionary
объекты.
После образования моста от NSDictionary
возразите против словаря Swift, Вы можете также нисходящий словарь к более определенному типу. Так же, как с downcasting массив Swift, downcasting словарь Swift, как гарантируют, не успешно выполнится. Результат нисходящего из [NSObject: AnyObject]
к более определенному типу с помощью as?
оператор является дополнительным значением.
Когда Вы бросаете в обратном направлении — от словаря Swift до NSDictionary
объект — ключи и значения должны быть экземплярами класса или bridgeable к экземпляру класса.
Можно также создать NSDictionary
возразите непосредственно от литерала словаря Swift, соблюдя те же правила образования моста, обрисованные в общих чертах выше. Когда Вы явно вводите константу или переменный как NSDictionary
возразите и присвойте его литерал словаря, Swift создает NSDictionary
объект вместо словаря Swift.
Типы данных основы
Swift обеспечивает удобное наложение для взаимодействия через интерфейс с типами данных, определенными в платформе Основы. Используйте это наложение для работы с типами как CGSize
и CGPoint
, использование синтаксиса, чувствующего себя естественным и объединенным с остальной частью языка Swift. Например, можно создать CGSize
структура с помощью этого синтаксиса:
Swift
let size = CGSize(width: 20, height: 40)
Наложение также позволяет Вам вызвать функции Основы на структурах естественным способом.
Swift
let rect = CGRect(x: 50, y: 50, width: 100, height: 100)
let width = rect.width // equivalent of CGRectGetWidth(rect)
let maxX = rect.maxY // equivalent of CGRectGetMaxY(rect)
Мосты Swift NSUInteger
и NSInteger
к Int
. Оба из этих типов прибывают через как Int
в основе APIs. Int
используется для непротиворечивости, когда это возможно, в Swift, но UInt
тип доступен при требовании типа целого без знака.
Функции основы
NSLog
доступно в Swift для журналирования к системной консоли. Вы используете тот же синтаксис форматирования, который Вы использовали бы в Objective C.
Swift
NSLog("%.7f", pi) // Logs "3.1415927" to the console
Swift также имеет функции печати как print
и println
доступный. Эти функции просты, мощны, и универсальны вследствие строковой интерполяции Swift. Они не распечатывают к системной консоли, но доступны для общих потребностей печати.
NSAssert
функции не переносят на Swift. Вместо этого используйте assert
функция.
Базовая основа
Базовые типы Основы автоматически импортируются как законченные классы Swift. Везде, где аннотации управления памятью были предоставлены, Swift автоматически управляет памятью Базовых объектов Основы, включая Базовые объекты Основы, что Вы инстанцируете себя. В Swift можно использовать каждую пару бесплатной соединенной мостом Основы и Базовых типов Основы взаимозаменяемо. Если Вы бросаете к образующему мост типу Основы сначала, можно также соединить некоторые бесплатные соединенные мостом Базовые типы Основы мостом к типам библиотеки стандарта Swift.
Повторно отображенные типы
Когда импорт Swift Базовые типы Основы, компилятор повторно отображает имена этих типов. Компилятор удаляет Касательно из конца каждого имени типа, потому что все классы Swift являются ссылочными типами, поэтому суффикс избыточен.
Базовая основа CFTypeRef
тип полностью повторно отображается на AnyObject
ввести. Везде, где Вы использовали бы CFTypeRef
, необходимо теперь использовать AnyObject
в Вашем коде.
Управляемые объекты памяти
Базовые объекты Основы, возвращенные из аннотируемого APIs, являются автоматически памятью, которой управляют в Swift — Вы не должны вызывать CFRetain
, CFRelease
, или CFAutorelease
функции самостоятельно. Если Вы возвращаете Базовые объекты Основы из своих собственных функций C и методов Objective C, аннотируете их также CF_RETURNS_RETAINED
или CF_RETURNS_NOT_RETAINED
. Компилятор автоматически вставляет вызовы управления памятью, когда он компилирует Код SWIFT, вызывающий этот APIs. Если Вы используете, только аннотировал APIs, косвенно не возвращающий Базовые объекты Основы, можно пропустить остальную часть этого раздела. Иначе, продолжите для приобретения знаний о работе с неуправляемыми Базовыми объектами Основы.
Неуправляемые объекты
Когда Swift импортирует APIs, не аннотированный, компилятор не может автоматически память управлять возвращенными Базовыми объектами Основы. Swift обертывает эти возвращенные Базовые объекты Основы в Unmanaged<T>
структура. Все косвенно возвращенные Базовые объекты Основы неуправляемы также. Например, вот неаннотируемая функция C:
Objective C
CFStringRef StringByAddingTwoStrings(CFStringRef string1, CFStringRef string2)
И вот то, как Swift импортирует его:
Swift
func StringByAddingTwoStrings(CFString!, CFString!) -> Unmanaged<CFString>!
При получении неуправляемого объекта из неаннотируемого API необходимо сразу преобразовать его в управляемый объект памяти перед работой с ним. Тем путем Swift может обработать управление памятью для Вас. Unmanaged<T>
структура обеспечивает два метода для преобразования неуправляемого объекта в управляемый объект памяти —takeUnretainedValue()
и takeRetainedValue()
. Оба из этих методов возвращают исходный, развернутый тип объекта. Вы выбираете, какой метод использовать на основе того, вызываете ли API Вы, возвращает несохраненный или сохраненный объект.
Например, предположите, что функция C выше не сохраняет CFString
объект прежде, чем возвратить его. Чтобы начать использовать объект, Вы используете takeUnretainedValue()
функция.
Swift
let memoryManagedResult = StringByAddingTwoStrings(str1, str2).takeUnretainedValue()
// memoryManagedResult is a memory managed CFString
Можно также вызвать retain()
, release()
, и autorelease()
методы на неуправляемых объектах, но этот подход не рекомендуется.