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