Swift dilində avtomatik yaddaş idarəetmə mexanizmi (ARC) necə işləyir?
sobes.tech Süni İntellekt
AI-dan cavab
ARC (Avtomatik Referans Sayma) nümunələrə istinadları avtomatik izləyir və idarə edir. O, nümunənin istifadə olunmayan yaddaşını azad edir, əgər ona qarşı güclü istinadlar qalmayıbsa. ARC yalnız sinif nümunələri ilə işləyir, struktur və ya enumerasiya ilə yox, çünki onlar dəyər tipləridir.
Nümunələr arasında üç növ istinad:
- Strong (Güclü): Nümunənin istinad sayğacını artıran istinad. Əsasən bütün istinadlar güclüdür.
- Weak (Zəif): Sayğacı artırmayan istinad. Güclü istinad dövrlərini qarşısını almaq üçün istifadə olunur.
weaktipli istinadlar həmişə opsionaldır, çünki nümunə hər zaman azad edilə bilər. - Unowned (Mülkiyyətsiz): Sayğacı artırmayan və nümunənin daha uzun müddət mövcud olacağına əmin olunduğu zaman istifadə olunan istinad. Zəruri deyil, lakin azad edilən nümunəyə giriş cəhdi icra zamanı xəta ilə nəticələnir.
Güclü istinad dövrləri, iki və ya daha çox sinif nümunəsinin bir-birinə güclü istinadlar saxlaması nəticəsində yaranır və ARC-nin onları azad etməsinə mane olur. Bu dövrləri həll etmək üçün weak və ya unowned istinadlar istifadə olunur.
Güclü istinad dövrünün nümunəsi:
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
}
deinit { // azad edilərkən çağırılır
print("\(name) azad edilir")
}
}
class Apartment {
let unit: String
var tenant: Person?
init(unit: String) {
self.unit = unit
}
deinit { // azad edilərkən çağırılır
print("Mənzil \(unit) azad edilir")
}
}
var john: Person?
var unit4A: Apartment?
john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil
unit4A = nil // Heç bir şey çap edilmir, çünki güclü istinad dövrü mövcuddur
Güclü istinad dövrünü weak ilə həll etmək:
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
}
deinit {
print("\(name) azad edilir")
}
}
class Apartment {
let unit: String
weak var tenant: Person? // Zəif istinad
init(unit: String) {
self.unit = unit
}
deinit {
print("Mənzil \(unit) azad edilir")
}
}
var john: Person?
var unit4A: Apartment?
john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil // Person azad edilir
unit4A = nil // Mənzil azad edilir
Güclü istinad dövrünü unowned ilə həll etmək:
class Customer {
let name: String
var card: CreditCard?
init(name: String) {
self.name = name
}
deinit {
print("\(name) azad edilir")
}
}
class CreditCard {
let number: UInt64
unowned let customer: Customer // Mülkiyyətsiz istinad
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
deinit {
print("Karta #\(number) azad edilir")
}
}
var john: Customer?
john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
john = nil // Customer və CreditCard azad edilir
ARC və closure-lərdə: Closure-lər də sinif nümunələrinə güclü dövrlər yarada bilər, onları tutaraq. Bu dövrləri qarşısını almaq üçün [weak self] və ya [unowned self] istifadə olunur.
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = { // lazy, self-dən əvvəl istifadə üçün
[unowned self] in // Məlumat tutma siyahısı
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) azad edilir")
}
}
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "salam, dünya")
print(paragraph!.asHTML())
paragraph = nil // HTMLElement azad edilir