← Назад к вопросам

Какие типы данных не работают с ARC?

1.0 Junior🔥 251 комментариев
#Управление памятью

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Типы данных, не управляемые ARC в Swift и Objective-C

ARC (Automatic Reference Counting) — это механизм автоматического управления памятью, который работает исключительно с экземплярами классов (reference types). Однако в Swift и Objective-C существуют типы данных, которые не подчиняются ARC, так как используют другие модели управления памятью. Вот основные категории:

1. Value Types (Значимые типы)

ARC неприменим, так как эти типы хранятся в стеке (или внутри других структур) и копируются при присваивании или передаче.

  • Структуры (struct):
struct Point {
    var x: Double
    var y: Double
}
var p1 = Point(x: 0, y: 0)
var p2 = p1 // Создаётся независимая копия, ARC не задействован.
  • Перечисления (enum):
enum CompassDirection {
    case north, south, east, west
}
var direction = CompassDirection.north
  • Кортежи (tuples) и скалярные типы (Int, Double, Bool, etc.) — также value types.

2. Типы, требующие ручного управления памятью

Unmanaged-объекты (Objective-C Core Foundation)

Некоторые API Core Foundation возвращают указатели на объекты, не управляемые ARC. Для них используется тип Unmanaged<T> или ручной вызов CFRetain/CFRelease.

import CoreFoundation
let cfString: CFString = "Hello" as CFString
let unmanaged = Unmanaged.passRetained(cfString)
// Требуется явное освобождение:
unmanaged.release()

C-указатели (UnsafePointer, UnsafeMutablePointer):

Указатели на память, выделенную вручную (например, через malloc), не управляются ARC.

let buffer = UnsafeMutablePointer<Int>.allocate(capacity: 10)
// Обязательно освобождать вручную:
buffer.deallocate()

3. Weak и Unowned ссылки

Хотя они используются с классами (ARC), сами по себе weak и unowned не увеличивают счётчик ссылок, поэтому объект может быть освобождён, если на него нет strong-ссылок.

class Person {
    weak var apartment: Apartment? // Не удерживает объект apartment
}

4. Objective-C: явное указание no-ARC

В Objective-C код можно скомпилировать без ARC (например, legacy-проекты). Тогда вся память управляется вручную через retain/release/autorelease.

5. Типы с ручным выделением памяти в системных фреймворках

  • C-структуры (например, CGPoint, CGRect из CoreGraphics).
  • Указатели на функции (function pointers).
  • Memory-mapped файлы или глобальная память (shared memory).

Ключевое отличие: Reference Types vs Value Types

Для наглядности рассмотрим пример:

class ClassExample { // Reference Type (управляется ARC)
    var value: Int = 0
}

struct StructExample { // Value Type (не управляется ARC)
    var value: Int = 0
}

var obj1 = ClassExample()
var obj2 = obj1 // obj2 ссылается на тот же объект, счётчик ссылок +1
obj2.value = 5
print(obj1.value) // 5, так как это один объект

var struct1 = StructExample()
var struct2 = struct1 // Создаётся независимая копия
struct2.value = 5
print(struct1.value) // 0, разные экземпляры

Итог

ARC управляет только объектами классов (reference types) в Swift и Objective-C. Все значимые типы (value types), низкоуровневые указатели, Core Foundation объекты (без аннотаций bridge) и weak/unowned ссылки напрямую не контролируются ARC. Это требует от разработчика осторожности при работе с unsafe-кодом и системными API, чтобы избежать утечек памяти или преждевременного освобождения ресурсов.