iOS'ta retain cycle'lar (tutma döngüleri) nedir?
sobes.tech yapay zeka
AI'dan gelen yanıt
İşlem döngüleri, iki veya daha fazla nesne birbirine güçlü referanslar içerdiğinde oluşur ve böylece "kapanmış bir döngü" oluşturur. Sonuç olarak, her nesnenin referans sayacı sıfıra ulaşmaz ve ARC (Otomatik Referans Sayımı) tarafından serbest bırakılamaz. Bu, nesneler kullanılmadıktan sonra bile bellekte kalmaya devam ettiği için bellek sızıntılarına yol açar.
Örnek:
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) başlatılıyor")
}
deinit {
print("\(name) sonlandırılıyor")
}
}
class Apartment {
let unit: String
var tenant: Person?
init(unit: String) {
self.unit = unit
print("Daire \(unit) başlatılıyor")
}
deinit {
print("Daire \(unit) sonlandırılıyor")
}
}
Bu örnekte, eğer Person nesnesi Apartment'a güçlü referanssa ve Apartment da Person'a güçlü referanssa, bu nesneleri serbest bırakmaya çalıştığınızda, nesneler silinmeyecektir çünkü referans sayacı sıfıra ulaşmaz.
İşlem döngülerini nasıl çözebilirsiniz:
weak veya unowned referanslar kullanın.
weak: Bağlantılı nesnenin yaşam döngüsü boyuncanilolabileceği durumlarda kullanılır. Referans otomatik olaraknilolur, nesne serbest bırakıldığında. Opsiyoneldir.unowned: Bağlantılı nesnenin, referans alan nesneden daha uzun veya aynı ömre sahip olduğu durumlarda kullanılır.nilolamaz.
weak kullanarak düzeltilmiş örnek:
tenant referansını Apartment sınıfında zayıf yapalım:
class Apartment {
let unit: String
weak var tenant: Person? // weak kullanıyoruz
init(unit: String) {
self.unit = unit
print("Daire \(unit) başlatılıyor")
}
deinit {
print("Daire \(unit) sonlandırılıyor")
}
}
Artık Person nesnesi serbest bırakıldığında, tenant referansı otomatik olarak nil olur ve döngü kırılır, böylece Apartment da serbest bırakılabilir.
weak ve unowned karşılaştırma tablosu:
| Özellik | weak |
unowned |
|---|---|---|
| Referans tipi | Opsiyonel | Opsiyonel olmayan |
nil olabilir mi? |
Evet, nesne serbest bırakıldığında | Hayır |
| Ne zaman kullanılır? | Nesne nil olabilecekse |
Nesne nil olmayacaksa |
| Performans | nil kontrolü nedeniyle biraz daha yavaş |
Biraz daha hızlı |
Ayrıca, işlem döngüleri kapanışlarda da oluşabilir.
Bir kapanış, örneğin self veya özellikleri yakalarsa, nesneye güçlü referans oluşturabilir. Eğer bu nesne de kapanışa güçlü referanssa (örneğin, özellik veya delege aracılığıyla), bir döngü oluşur.
İşlem döngülerini kapanışlarda nasıl önlersiniz:
Capture list kullanın.
class SomeClass {
var value = 0
func doSomethingDelayed() {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in // weak self ile capture list
guard let self = self else { return } // `self`'i `nil` kontrolü
self.value += 1
print("Değer şu an \(self.value)")
}
}
}
Bu örnekte, [weak self] self'e zayıf bir referans oluşturur ve böylece işlem döngüsü önlenir.