І посилання, weak
і unowned
посилання не створюють strong
затримку на згаданому об'єкті (він також не збільшує кількість утримування, щоб не допустити ARC переходити згаданий об'єкт).
Але чому два ключові слова? Ця відмінність пов'язана з тим, що Optional
типи вбудовані в мову Swift. Довга коротка розповідь про них: опціональні типи забезпечують безпеку пам’яті (це чудово працює з правилами конструктора Swift - які суворі для того, щоб забезпечити цю перевагу).
weak
Посилання допускає можливість його стати nil
(це відбувається автоматично , коли об'єкт посилання звільняється), тому тип вашої власності повинен бути обов'язково - так що ви, як програміст, зобов'язані перевірити його , перш ніж використовувати його ( в основному компілятор змушує вас, наскільки це можливо, написати безпечний код).
An unowned
посилання передбачає , що він ніколи не стане в nil
протягом його життя. Під час ініціалізації необхідно встановити невідоме посилання - це означає, що посилання буде визначено як необов'язковий тип, який можна безпечно використовувати без перевірок. Якщо якимось чином об'єкт, на який йдеться, буде розміщений, тоді додаток вийде з ладу, коли буде використана невідома посилання.
З документів Apple :
Використовуйте слабку посилання, коли це дійсно, щоб ця посилання стала нульовою в якийсь момент її життя. І навпаки, використовуйте невідому посилання, коли знаєте, що посилання ніколи не буде нульовою після того, як вона була встановлена під час ініціалізації.
У документах є кілька прикладів, які обговорюють утримувані цикли та способи їх розбиття. Усі ці приклади витягнуті з документів .
Приклад weak
ключового слова:
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
}
class Apartment {
let number: Int
init(number: Int) { self.number = number }
weak var tenant: Person?
}
А тепер для деяких мистецтв ASCII (ви повинні переглянути документи - вони мають досить діаграми):
Person ===(strong)==> Apartment
Person <==(weak)===== Apartment
Приклад Person
і Apartment
приклад показує ситуацію, коли дві властивості, обом з яких дозволено бути нульовими, можуть викликати сильний еталонний цикл. Цей сценарій найкраще вирішити зі слабким посиланням. Обидва суб'єкти можуть існувати без жорсткої залежності від інших.
Приклад unowned
ключового слова:
class Customer {
let name: String
var card: CreditCard?
init(name: String) { self.name = name }
}
class CreditCard {
let number: UInt64
unowned let customer: Customer
init(number: UInt64, customer: Customer) { self.number = number; self.customer = customer }
}
У цьому прикладі Customer
може бути , а може і не бути CreditCard
, але CreditCard
завжди буде пов'язано з a Customer
. Щоб представити це, Customer
клас має необов'язкове card
властивість, але CreditCard
клас має необов'язкове (і невідоме) customer
властивість.
Customer ===(strong)==> CreditCard
Customer <==(unowned)== CreditCard
Приклад Customer
і CreditCard
приклад показує ситуацію, коли одна властивість, якій дозволено бути нульовою, а інша властивість, яка не може бути нульовою, може викликати сильний еталонний цикл. Цей сценарій найкраще вирішити за допомогою невідомої посилання.
Примітка від Apple:
Слабкі посилання повинні бути оголошені змінними, щоб вказати, що їх значення може змінюватися під час виконання. Слабка посилання не може бути оголошена постійною.
Існує також третій сценарій, коли обидва властивості завжди повинні мати значення, і жодна властивість ніколи не повинна бути нульовою після завершення ініціалізації.
Є також класичні сценарії збереження циклу, яких слід уникати при роботі із закриттями.
Для цього я закликаю вас відвідати документи Apple або прочитати книгу .