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

Какие знаешь требования к weak свойствам?

2.0 Middle🔥 121 комментариев
#Управление памятью#Язык Swift

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

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

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

Требования к weak свойствам в iOS/macOS разработке

Weak свойства (weak) — это один из механизмов управления памятью в Swift/Objective-C, который помогает предотвращать сильные циклы ссылок (retain cycles). Вот ключевые требования и особенности:

1. Только для ссылочных типов

weak можно применять только к классам (reference types), но не к структурам или перечислениям (value types), поскольку weak работает с подсчётом ссылок (ARC).

class Person {
    weak var apartment: Apartment? // ОК: класс
    // weak var name: String? // Ошибка: String - структура
}

2. Всегда optional

weak свойства всегда должны быть optional (? или !), так как ARC может обнулить (nil) weak ссылку, когда объект освобождается.

weak var delegate: SomeDelegate? // Правильно
// weak var delegate: SomeDelegate // Ошибка: non-optional

3. Автоматическое обнуление (zeroing)

Когда объект, на который указывает weak ссылка, освобождается, ARC автоматически устанавливает weak свойство в nil. Это безопасно предотвращает висячие указатели.

var parent: Parent? = Parent()
weak var child = parent?.child // weak ссылка
parent = nil // Если child больше не удерживается, child станет nil

4. Не увеличивает счётчик ссылок

weak ссылка не увеличивает retain count объекта. Это отличает weak от strong (сильной) ссылки.

class MyClass {
    weak var other: MyClass?
}

var obj1: MyClass? = MyClass()
var obj2: MyClass? = MyClass()
obj1?.other = obj2 // obj2 retain count не увеличивается

5. Типичные сценарии использования

  • Делегаты (delegates) и источники данных (data sources) — чтобы избежать циклов между view controller и его делегатом.
  • Родитель-потомок отношений — когда потомок не должен удерживать родителя.
  • Замыкания (closures) — захват weak self внутри замыканий, чтобы избежать retain cycles.
  • Outlet'ы в Interface Builder — все @IBOutlet свойства по умолчанию weak, так как view уже удерживается своим superview.
class ViewController: UIViewController {
    @IBOutlet weak var titleLabel: UILabel! // IBOutlet
    weak var delegate: DataDelegate? // делегат
}

6. Отличие от unowned

weak всегда optional, unowned — non-optional, но предполагает, что объект живёт дольше. unowned не обнуляется, но приводит к крашу при доступе к освобождённому объекту.

weak var safeWeak: SomeClass? // обнуляемый
unowned let riskyUnowned: SomeClass // не обнуляемый, опасно

7. Особенности в Objective-C

В Objective-C weak свойства требуют поддержки runtime (iOS 5+ / macOS 10.7+) и используются с qualifier __weak.

@property (nonatomic, weak) id<MyDelegate> delegate;

8. Производительность

Работа с weak ссылками требует дополнительных накладных расходов, так как ARC поддерживает дополнительную таблицу weak ссылок и выполняет обнуление. Это обычно незначительно, но важно в высоконагруженных частях кода.

9. Потокобезопасность

Доступ к weak свойству не атомарен по умолчанию (если не объявлено как atomic в Objective-C). В многопоточном коде следует синхронизировать доступ.

// Потенциально небезопасно в многопоточности
if let object = weakProperty {
    // объект может стать nil между проверкой и использованием
}

10. Проверка существования

Всегда используйте optional binding для безопасного доступа к weak свойствам.

if let strongReference = weakProperty {
    // безопасная работа с объектом
} else {
    // объект был освобождён
}

Резюме: weak свойства — важный инструмент для управления памятью в ARC-средах. Они требуют понимания их optional-природы, сценариев применения и отличий от других типов ссылок. Правильное использование weak предотвращает утечки памяти и делает код стабильнее.