Для чего в Swift используется тип AnyObject?

Ответ

AnyObject — это протокол, представляющий экземпляр любого класса. Он используется в Swift для типобезопасной работы с объектами, когда конкретный тип класса неизвестен или может быть разным.

Основные сценарии использования:

  1. Совместимость с Objective-C API: Аналог id. Позволяет передавать объекты классов в API, ожидающие нетипизированные ссылки.
  2. Хранение гетерогенных коллекций объектов классов:
    let uiComponents: [AnyObject] = [UIButton(), UILabel(), UIImageView()]
  3. Проверка типа и приведение (type casting):
    for object in uiComponents {
        if let button = object as? UIButton {
            button.setTitle("Tap", for: .normal)
        }
    }
  4. Определение протоколов только для классов (class-only protocols):
    protocol MyDelegate: AnyObject { // Делегат должен быть классом
        func didUpdate()
    }

Важное отличие от Any:

  • AnyObject ограничен только классами.
  • Any может представлять экземпляр любого типа, включая структуры, перечисления, функции и классы.
let mixedArray: [Any] = ["String", 42, UIView()] // Допустимо
let classArray: [AnyObject] = [UIView(), NSObject()] // Только классы
// let errorArray: [AnyObject] = ["String", 42] // Ошибка: String и Int - структуры

Ответ 18+ 🔞

А, AnyObject, ёпта, классика жанра! Это ж как тот универсальный гаечный ключ в бардачке, который на всё похож, но по факту — только на гайки от колёс подходит, блядь.

Вот смотри, представь себе такую хуйню. Это протокол, который орет на весь мир: «Я — экземпляр любого класса!». Не структура, не енумчик, не какая-то там функция-замыкание, а именно класс, сука. Объект, который живёт в куче и на него можно пальцем тыкать.

Зачем эта мартышлюшка нужна? Да по разным поводам, блядь.

  1. Совместимость с Objective-C, этот старый дед. Там же был тип id — «ой, всё!». Так вот AnyObject в Swift — это его типобезопасный внучок, который хоть как-то пытается за порядком следить, когда ты суёшь что попало в старые АПИшки. Передал — и вроде не обосрался сразу.
  2. Сборная солянка из объектов. Ну, типа, собрал в кучу всякую хуйню, но только ту, что является классом.
    let uiComponents: [AnyObject] = [UIButton(), UILabel(), UIImageView()]

    Кнопки, лейблы, вьюхи — все довольны, все классы. Попробуй туда Int или String сунуть — получишь по ебалу от компилятора, ибо это структуры, а не классы, ёпта!

  3. Проверка и приведение типов, игра в угадайку. Достал из этой кучи объект и думаешь: «А не кнопка ли это, блядь?».
    for object in uiComponents {
        if let button = object as? UIButton { // О, да это ж кнопка!
            button.setTitle("Тапни меня", for: .normal)
        }
    }
  4. Протоколы только для классов. Вот это важная хуйня! Когда пишешь протокол для делегата, и тебе надо, чтобы он был классом (чтобы слабую ссылку weak сделать и циклы не плодить), ты его ограничиваешь AnyObject.
    protocol MyDelegate: AnyObject { // Делегат — только класс, никаких структур!
        func didUpdate()
    }

    Иначе как ты на него слабую ссылку сделаешь, а? Нельзя же, блядь.

А теперь главное, чтобы не обосраться: отличие от Any. Вот это, блядь, частая засада. Any — это вообще что угодно. Вообще. Структура, перечисление, функция, класс — всё сойдёт, хоть потрогай. А AnyObject — это только классы, сука. Только они.

let mixedArray: [Any] = ["Строка", 42, UIView()] // Всё норм, и строка (структура), и число, и вьюха.
let classArray: [AnyObject] = [UIView(), NSObject()] // Тоже ок, оба класса.
// let errorArray: [AnyObject] = ["Строка", 42] // ПИЗДЕЦ! Компилятор тебе сейчас ебальник набьёт! String и Int — это структуры, им тут не место!

Короче, AnyObject — это такой забор, который говорит: «Сюда только классы, остальные — нахуй». А Any — это поле чудес в стране дураков, куда можно притащить вообще что угодно, а потом разбираться. Выбирай с умом, а то овердохуища проблем на ровном месте нахватаешь.