Swift xotira
Swift xotirani boshqarish
ARC’ni tushuning, weak/unowned yordamida saqlash sikllaridan (retain cycles) qoching va closure qamrovlarini xavfsiz boshqaring.
Havolalarni avtomatik sanash (ARC)
Sinflar havola tiplaridir.
Swift sinf nusxalarini kuzatib borish va ularga kuchli havolalar qolmaganda ularni avtomatik bo‘shatish uchun ARC’dan foydalanadi.
Misol
class Box {
let name: String
init(_ n: String) { name = n; print("init \(n)") }
deinit { print("deinit \(name)") }
}
do {
let b = Box("A")
print("in scope")
}
print("after scope")
Ushbu misolda Box nusxasi ko‘rinish sohasidan chiqqanda ARC uni avtomatik ravishda xotiradan bo‘shatishi ko‘rsatilgan.
Maslahat: Sinf nusxalari o‘rtasidagi kuchli havola sikllaridan qochish uchun weak dan foydalaning.
Kuchli havola sikllari
Kuchli havola sikli ikki sinf nusxasi bir-biriga kuchli havolalarni saqlaganda yuzaga keladi va ARC’ning ularni xotiradan bo‘shatishiga to‘sqinlik qiladi.
Siklni uzish uchun bir tomonni weak (yoki mos bo‘lsa, unowned) deb belgilang.
Misol
class Person {
let name: String
var apartment: Apartment?
init(name: String) { self.name = name }
deinit { print("Person deinit") }
}
class Apartment {
let unit: String
weak var tenant: Person? // weak breaks the cycle
init(unit: String) { self.unit = unit }
deinit { print("Apartment deinit") }
}
do {
var john: Person? = Person(name: "John")
var unit: Apartment? = Apartment(unit: "4A")
john!.apartment = unit
unit!.tenant = john
john = nil // Person deinit
unit = nil // Apartment deinit
}
tenant ni weak deb e’lon qilish siklni uzadi, shuning uchun kuchli havolalari nil ga tenglanganda ikkala obyekt ham xotiradan bo‘shatiladi.
Closure’lar va qamrov ro‘yxatlari (weak self)
Closure’lar standart holatda o‘zgaruvchilarni qamrab oladi.
Sinf self ga murojaat qiladigan closure’ni saqlasa, saqlash sikllaridan qochish uchun [weak self] kabi qamrov ro‘yxatidan (capture list) foydalaning.
Misol
class Loader {
var onComplete: (() -> Void)?
func load() {
// simulate async completion
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
guard let self = self else { return }
print("Finished: \(self)")
self.onComplete?()
}
}
deinit { print("Loader deinit") }
}
do {
let loader = Loader()
loader.onComplete = { print("done callback") }
loader.load()
}
// loader can be deallocated if nothing else references it
W3Schools Pathfinder
Yutuqlaringizni kuzating – bu bepul!
