За какво е нужен типът на референциите unowned?
sobes.tech AI
Отговор от AI
unowned препратки са необходими за разрешаване на циклични препратки (retain cycles) между обекти, когато и двата обекта имат силна препратка един към друг, но един от тях има по-кратък или равен жизнен цикъл спрямо другия.
unowned се използва, когато е известно, че препратеният обект няма да бъде nil през цялото време на живота на обекта, който съдържа препратката. За разлика от weak, при unowned достъпът до препратката не използва Optional. Ако обектът, към който се препраща с unowned, бъде деалокирана преди обекта с unowned препратка, ще настъпи crash.
Пример за използване в затваряния:
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) се инициализира")
}
deinit {
print("\(name) се деинициализира")
}
}
class Apartment {
let unit: String
// Използваме `unowned`, тъй като е известно, че
// Apartment не може да съществува без Person
// (в този контекст). Person може да бъде nil,
// но ако Apartment съществува, Person също съществува.
unowned let tenant: Person
init(unit: String, tenant: Person) {
self.unit = unit
self.tenant = tenant
print("Apartment \(unit) се инициализира")
}
deinit {
print("Apartment \(unit) се деинициализира")
}
}
var john: Person?
var unit4A: Apartment?
john = Person(name: "John Appleseed")
// В този пример tenant може да бъде nil, затова `unowned`
unit4A = Apartment(unit: "4A", tenant: john!)
john!.apartment = unit4A
// Разкъсваме силните препратки, за да проверим деалокацията
john = nil
unit4A = nil
В този пример Person има силна препратка към Apartment (var apartment: Apartment?). Apartment може да има силна препратка към Person, което ще доведе до цикъл. Въпреки това, тъй като в този контекст Apartment логически не може да съществува без Person (който го наема), връзката от Apartment към Person се прави с unowned. Така, при нулиране на john = nil, Person се деалокира, а след това (тъй като няма силни препратки към Apartment) и Apartment се деалокира.
Основните разлики от weak:
- Животен цикъл:
unownedсе използва, когато препратеният обект има същия или по-дълъг жизнен цикъл.weakсе използва, когато препратеният обект може да бъде деалокирана по-рано. - Optional:
unownedне е Optional (освен ако не е обявен катоunowned optional).weakвинаги е Optional. - Безопасност: Достъпът до свойство с
unownedпрепратка към вече деалокирал се обект ще доведе до crash. Достъпът доweakпрепратка ще върнеnil.
Така, unowned е не-отстъпваща (non-owning) препратка, която се използва, когато се гарантира съществуването на препратения обект, докато съществува обект с unowned препратка.