Any и AnyObject в Swift. В чем их различие?
Довольно долгое время в своих проектах при написании кода я использовал тип Any, например при обработке JSON данных. Но также я знал что есть и второй тип — AnyObject. И недавно я задумался о разнице между этими двумя типами.
Согласно документации Apple:
- Any — может представлять экземпляр любого типа
- AnyObject — может представлять экземпляр любого класса
Если сказать чуть проще, то:
- Any используется для всех типов
AnyObject — используется для типов Class
Проверим на деле эти два типа. Начнем с типа Any
Для этого создадим массив с типом Any, и распечатаем его.
Как мы видим, Any позволяет работать с различными типами данных одновременно (String, Int).
Согласно документации, элементы (String и Int) в этом массиве являются структурами, которые являются типами значений, поэтому, теоретически, AnyObject не должен работать.
Чтобы проверить это, был создан идентичный массив, с типом AnyObject.
Как и ожидалось, компилятор выдает нам ошибку о невозможности преобразовании типа «String/Int» к типу AnyObject
Но давайте все таки попробуем привести три наших типа к AnyObject и распечатать результат.
Ошибка компилятора исчезла. Как мы видим, строка Macbook явно выглядит как строка, но не имеет привычных кавычек как у типа String в Swift.
Попробуем распечатать массив с помощью цикла, чтобы проверить их фактический тип.
Строка имеет тип String. Как было сказано раньше, строки в Swift являются структурами, а не типами классов. Значит, мы не должны иметь возможность использовать их как AnyObject.
Проведем еще пару экспериментов с нашим массивом. Попробуем проверить их на типы из Objective‑C: NSString и NSNumber.
Строка является NSString, а числовой элемент является NSNumber. И оба этих типа являются ссылочными в Objective‑C.
Так почему такое происходит?
Как часть своей совместимости с Objective‑C, Swift предлагает удобные и эффективные способы работы с платформами Cocoa.
Swift автоматически преобразует некоторые типы Objective‑C в типы Swift, а некоторые типы Swift в типы Objective‑C. Типы, которые можно конвертировать между Objective‑C и Swift, называются соединенными.
Другими словами, компилятор делает все возможное, чтобы быть гибким в обработке таких типов посредством автоматического преобразования и создания «мостов», в то же время предотвращая сбои приложения.
Когда же использовать AnyObject?
Как говорится в документации Apple, AnyObject может быть использован для работы с объектами, которые являются производными от Class, но не имеют общего корневого класса.
В Swift 3 тип id в Objective‑C теперь отображается на тип Any в Swift, который описывает значение любого типа, будь то класс, перечисление, структура или любой другой тип Swift. Это изменение делает API-интерфейсы Objective‑C более гибкими в Swift, поскольку определяемые Swift типы значений могут передаваться в Objective‑C API-интерфейсы и извлекаться как типы Swift, что устраняет необходимость в ручных «блочных» типах.
Таким образом, AnyObject желательно использовать когда вы хотите ограничить протокол, чтобы его можно было использовать лишь с классами, а Any в остальных случаях.
Спасибо за чтение, надеюсь что этот пост помог вам разобраться в чем разница между Any и AnyObject.
На vc.ru остались одни юные программисты?(учитывая что у статьи положительный рейтинг, а тема статьи это основы основ и есть в любом простом учебнике или документации)
.
Я тоже отношусь к программистам, но все же тематика у vc совсем другая, поэтому ставлю жирный downvote.
То есть если бы это была статья для продвинутых, то это бы подошло под тематику vc? :)
Автору спасибо.
нет. vc вообще не про код, помимо этого статья абсолютно не несет смысловой нагрузки
Разработка
Сообщество разработчиков: публикации о личном опыте, выдающиеся приемы при решении рутинных задач, полезные материалы для профессионального роста.
В общем, классический мир разработки, системного администрирования и QA.
Тогда про что же ещё vc.ru и подраздел Разработка?
В общем нужно спользовать Any и спать спокойно
Так а в чем разница
protocol A: class
protocol B: AnyObject
?
Разницы между class'ом и AnyObject'ом нет никакой. Вы можете использовать и то, и другое) Если вы откроете Xcode, найдете какой-нибудь протокол с одним из этих типов, и посмотрите QuickHelp, то увидите, что они оба являются AnyObject
Прим: