Ответ
Различия коренятся в фундаментальных парадигмах языков: 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. Выбирай, что тебе ближе: порядок или приключения, которые могут закончиться крешем.