Назад к вопросам
Middle
93
questionbank
Какие виды ссылок существуют в Swift?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
В Swift существуют три основных вида ссылок на экземпляры классов:
-
Сильная ссылка (Strong Reference):
- Это тип ссылки по умолчанию.
- Сильная ссылка увеличивает счетчик ссылок объекта.
- Объект не будет освобожден из памяти до тех пор, пока на него есть хотя бы одна сильная ссылка.
- Основная причина утечек памяти в случае циклических сильных ссылок (
strong reference cycles).
class Person { let name: String init(name: String) { self.name = name } deinit { print("\(name) is being deinitialized") } } var reference1: Person? = Person(name: "John") // reference1 теперь сильная ссылка, счетчик ссылок Person увеличивается -
Слабая ссылка (Weak Reference):
- Объявляется с использованием ключевого слова
weak. - Слабая ссылка не увеличивает счетчик ссылок объекта.
- Используется для предотвращения
strong reference cycles. - Всегда является опциональной (
Optional), потому что объект, на который указывает слабая ссылка, может быть деинициализирован в любое время. При деинициализации объекта слабая ссылка автоматически становитсяnil.
class Apartment { let unit: String weak var tenant: Person? // Слабая ссылка init(unit: String) { self.unit = unit } deinit { print("Apartment \(unit) is being deinitialized") } } var john: Person? = Person(name: "John") var unit4A: Apartment? = Apartment(unit: "4A") john?.apartment = unit4A // Если бы Apartment имел сильную ссылку на Person unit4A?.tenant = john // Слабая ссылка // После сброса сильных ссылок, объекты будут деинициализированы john = nil unit4A = nil // Вывод: "John is being deinitialized", "Apartment 4A is being deinitialized" // Если бы tenant была сильной ссылкой, произошла бы утечка памяти (strong cycle) - Объявляется с использованием ключевого слова
-
Бесхозная ссылка (Unowned Reference):
- Объявляется с использованием ключевого слова
unowned. - Подобно слабой ссылке, не увеличивает счетчик ссылок объекта.
- Используется также для предотвращения
strong reference cycles. - В отличие от
weak, не является опциональной (Optional) и предполагает, что объект, на который она указывает, будет существовать в течение всего "срока жизни" бесхозной ссылки. - Если объект, на который указывает
unownedссылка, деинициализируется до того, какunownedссылка станет недействительной, произойдет ошибка выполнения (runtime error). - Подходит для ситуаций, когда один объект всегда существует, пока существует другой связанный с ним объект, но не наоборот (например, "родитель-ребенок", где родитель владеет ребенком, но ребенок не владеет родителем сильно).
class Customer { let name: String var card: CreditCard? init(name: String) { self.name = name } deinit { print("\(name) is being deinitialized") } } class CreditCard { let number: Int unowned let customer: Customer // Бесхозная ссылка init(number: Int, customer: Customer) { self.number = number self.customer = customer // Присваивание бесхозной ссылки безопасно в init } deinit { print("Card #\(number) is being deinitialized") } } var john: Customer? = Customer(name: "John Doe") john?.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) // Сброс сильной ссылки на Customer john = nil // Вывод: "John Doe is being deinitialized", "Card #1234567890123456 is being deinitialized" // Бесхозная ссылка на customer в CreditCard была действительна, пока customer существовал. // Если бы CreditCard жил дольше Customer и мы попытались обратиться к customer через бесхозную ссылку, произошла бы ошибка. - Объявляется с использованием ключевого слова
Ключевое различие между weak и unowned:
weak: объект может бытьnil. Используйте, когда срок жизни объектов не связан строго (один может существовать без другого).unowned: объект не может бытьnilпосле инициализации. Используйте, когда вы уверены, что ссылаемый объект будет существовать как минимум до тех пор, пока существует ссылающийся объект.