Middle
Дар Swift кадом намудҳои пайванд вуҷуд доранд?
sobes.tech AI
Ҷавоб аз 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посилання, деінціалізується раніше, ніж стане недійсним, виникне помилка виконання (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після ініціалізації. Використовуйте, коли ви впевнені, що на об'єкт посилається, він існуватиме щонайменше до того, як існуватиме посилаючий об'єкт.