В чем разница между коллекциями в Swift (Array, Dictionary, Set) и их аналогами в Objective-C (NSArray, NSDictionary, NSSet)?

Ответ

Различия коренятся в фундаментальных парадигмах языков: Swift — типобезопасный, с акцентом на value types, Objective-C — динамический, с reference types.

Характеристика Swift коллекции (Array<Element>, Dictionary<Key, Value>, Set<Element>) Objective-C коллекции (NSArray, NSDictionary, NSSet)
Типизация Строгая, через Generics. Компилятор знает тип элементов. Динамическая (id). Хранят объекты типа id (указатель на любой NSObject).
Семантика типа Value types (значимые). При присваивании копируется содержимое (с оптимизацией COW). Reference types (ссылочные). При присваивании копируется указатель на один и тот же объект.
Изменяемость Определяется объявлением (let = immutable, var = mutable). Один тип. Определяется классом. Есть immutable (NSArray) и mutable (NSMutableArray) версии.
Безопасность Высокая. Ошибки несоответствия типов ловятся на этапе компиляции. Низкая. Ошибки "unrecognized selector" возможны в runtime при неверном приведении типа.
Взаимодействие Автоматически мостится (bridged) к соответствующим Objective-C коллекциям при передаче в Cocoa API. Может использоваться в Swift как [Any] или [AnyHashable: Any]. Требует приведения типов.

Пример Swift (безопасность и типизация):

var swiftArray: [Int] = [1, 2, 3]
swiftArray.append(4) // OK
// swiftArray.append("text") // Ошибка компиляции: Cannot convert value...

Пример Objective-C (динамичность):

NSArray *objcArray = @[@1, @2, @3, @"four"]; // Могут быть объекты разных типов
NSNumber *first = objcArray[0]; // OK
NSString *third = objcArray[3]; // OK, но требует знания типа
// NSString *second = objcArray[1]; // Runtime crash (NSNumber не NSString)

Вывод: Swift коллекции безопаснее и выразительнее. Objective-C коллекции используются для совместимости с legacy кодом или Cocoa API, ожидающим NSArray.

Ответ 18+ 🔞

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

Короче, вся разница в самой сути, в парадигме, ёпта. Swift — это типобезопасный зануда, который всё проверяет и обожает value types. А Objective-C — это старый динамичный раздолбай, который работает по принципу «и так сойдёт» и таскает везде ссылки.

Вот, смотри табличку, чтобы не быть голословным:

Признак Swift коллекции (Array<Element>, Dictionary<Key, Value>, Set<Element>) Objective-C коллекции (NSArray, NSDictionary, NSSet)
Типизация Строгая, через дженерики. Компилятор, блядь, знает, что у тебя в коробке лежит. Не подсунешь ему хуйню. Динамическая (id). Там лежит просто указатель id на какой-то NSObject. Может быть что угодно, хоть ты ебал его в сраку.
Семантика типа Value types (значимые). Скопировал — получил свою отдельную, новую коробку (ну, с умной оптимизацией COW, чтобы не копировать зря). Reference types (ссылочные). Скопировал — получил бумажку с адресом той же самой коробки. Пнул её — все, кто смотрит на этот адрес, увидят, что она упала.
Изменяемость Зависит от объявления. let — заморозил нахуй, var — делай что хочешь. Один тип на оба случая. Зависит от класса. Есть неизменяемый NSArray и его шальной братан NSMutableArray. Два разных класса, блядь.
Безопасность Высокая, мать его. Ошибки типа «хочу запихнуть строку в массив чисел» ловятся ещё при компиляции. Спи спокойно. Низкая, пиздец. Ошибки вроде «unrecognized selector» вылезут тебе в рантайме, когда ты уже всё собрал и запустил. Веселье!
Взаимодействие Автоматически мостится к Objective-C коллекциям, когда суёшь их в старые Cocoa API. Умно. В Swift'е они предстают как [Any] или [AnyHashable: Any]. И требуют, сука, постоянного приведения типов.

Вот тебе пример на Swift (красота и безопасность):

var swiftArray: [Int] = [1, 2, 3]
swiftArray.append(4) // Всё ок
// swiftArray.append("text") // Ошибка компиляции: Cannot convert value... Иди нахуй со своей строкой, тут числа!

А вот пример на Objective-C (свобода и анархия):

NSArray *objcArray = @[@1, @2, @3, @"four"]; // Могут быть объекты ЛЮБЫХ типов, ёбта!
NSNumber *first = objcArray[0]; // Ну ок
NSString *third = objcArray[3]; // Тоже ок, но ты должен ЗНАТЬ, что там строка
// NSString *second = objcArray[1]; // Runtime crash, пиздец! Там же NSNumber, а не NSString! Привет от unrecognized selector!

Вывод, блядь: Swift коллекции — это безопасно и выразительно. Objective-C коллекции — это для совместимости со старым кодом или когда лезешь в дебри Cocoa, которые ждут NSArray. Выбирай, что тебе ближе: порядок или приключения, которые могут закончиться крешем.