Назад к вопросам
Junior
129
questionbank

В чем разница между слабыми и сильными ссылками?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Разница в механизме управления памятью (ARC - Automatic Reference Counting).

  • Сильная ссылка (Strong reference): Повышает счетчик ссылок объекта на 1. Объект не может быть освобожден из памяти, пока на него существует хотя бы одна сильная ссылка. Это поведение по умолчанию для свойств и переменных в Swift.

  • Слабая ссылка (Weak reference): Не повышает счетчик ссылок объекта. Используются для предотвращения циклических ссылок, когда два или более объекта имеют сильные ссылки друг на друга, создавая утечку памяти. Слабые ссылки всегда опциональны (Optional), потому что объект, на который они ссылаются, может быть деаллоцирован в любое время. Если объект освобожден, слабая ссылка автоматически становится nil.

Пример циклической ссылки и ее предотвращения с помощью слабой ссылки:

class Person {
    let name: String
    var apartment: Apartment? // Strong reference here initially
    init(name: String) { self.name = name }
    deinit { print("\(name) is being deinitialized") }
}

class Apartment {
    let unit: String
    weak var tenant: Person? // Weekly reference here
    init(unit: String) { self.unit = unit }
    deinit { print("Apartment \(unit) is being deinitialized") }
}

var john: Person? // Person instance
var unit4A: Apartment? // Apartment instance

john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

// Creating a strong reference cycle:
// john has a strong reference to apartment
// apartment has a strong reference to person
john!.apartment = unit4A
unit4A!.tenant = john // This must be weak to break the cycle

john = nil // Setting john to nil won't deallocate it if the cycle exists
unit4A = nil // Setting unit4A to nil won't deallocate it if the cycle exists

// Expected output when using weak reference for tenant:
// John Appleseed is being deinitialized
// Apartment 4A is being deinitialized

Без weak для tenant, деинициализаторы не были бы вызваны, что указывает на утечку памяти.