Middle
Millised lingid Swiftis eksisteerivad?
sobes.tech AI
Vastus AI-lt
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 помилка (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 // Ініціалізація безтурботної посилання безпечно } 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" // `CreditCard`-у `customer` посилання було дійсним, поки `customer` існував. // Якщо б `CreditCard` жив довше за `Customer` і ми спробували звернутися до `customer` через `unowned` посилання, сталася б помилка. - Оголошується за допомогою слова
Ключова різниця між weak і unowned:
weak: об'єкт може бутиnil. Використовуйте, коли тривалість життя об'єктів не строго пов'язана (один може існувати без іншого).unowned: об'єкт не може бутиnilпісля ініціалізації. Використовуйте, коли ви впевнені, що посилається об'єкт буде існувати як мінімум до того, як існуватиме посилаючий об'єкт.