Middle
iOS'taki bellek yönetiminden bahsedin.
sobes.tech yapay zeka
AI'dan gelen yanıt
iOS, bellek yönetimi için otomatik referans sayımı (ARC) kullanır. ARC, referans kalmayınca nesneleri otomatik olarak serbest bırakır.
Ana kavramlar:
- Güçlü Referans: Nesnenin referans sayacını artırır. Nesne, güçlü referanslar kalmadıkça serbest bırakılmaz.
- Zayıf Referans: Referans sayacını artırmaz. Güçlü döngüleri önlemek için kullanılır. Serbest bırakılabilecek bir nesneye referans verir. Nesne serbest bırakılırsa, zayıf referans
nilolur. - Sahipsiz Referans (unowned): Zayıf ile benzer, referans sayacını artırmaz. Referans verilen nesne yaşam döngüsü aynı veya daha uzun olan nesneler için kullanılır. Nesne serbest bırakıldığında, sahipsiz referans
nilolmaz. Serbest bırakılan nesneye sahipsiz referansla erişim hatası verir.
Güçlü Referans Döngüleri (Retain Cycles): İki veya daha fazla nesne birbirine güçlü referanslar ile bağlandığında oluşur ve serbest bırakılmalarını engeller. Zayıf veya sahipsiz referanslar kullanılarak çözülür.
Ö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? // Güçlü referans, döngüye neden olur
init(unit: String) {
self.unit = unit
print("Daire \(unit) başlatılıyor")
}
deinit {
print("Daire \(unit) sonlandırılıyor")
}
}
var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john // Döngü burada oluşur
john = nil
unit4A = nil
// Serbest bırakma metodları çağrılmaz çünkü döngü var
Çözüm weak kullanımıyla:
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
weak var tenant: Person? // Döngüyü önlemek için weak referans kullan
init(unit: String) {
self.unit = unit
print("Daire \(unit) başlatılıyor")
}
deinit {
print("Daire \(unit) sonlandırılıyor")
}
}
var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil
unit4A = nil
// Her iki nesne de doğru şekilde sonlandırılır
Sahipsiz (unowned) vs Zayıf (weak):
weakkullanılır, referansnilolma ihtimali varsa (nesne önce serbest bırakılabilir).unownedkullanılır, referans her zaman bir değer olacaksa (referans verilen nesne daha uzun veya eşit yaşam döngüsüne sahipse).
Kapanışlar (Closures) ve döngüler:
Kapanışlar, nesnelere referanslar yakalayabilir ve güçlü döngüler oluşturabilir. Bu, yakalama listesi (capture list) kullanılarak çözülür.
Örnek:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
[weak self] in // self'yi zayıf yakala
guard let self = self else {
return ""
}
var html = "<\(self.name)"
if let text = self.text {
html += ">\(text)</\(self.name)>"
} else {
html += " />"
}
return html
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) sonlandırılıyor")
}
}
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "merhaba, dünya")
print(paragraph!.asHTML())
paragraph = nil
// Nesne sonlandırılır
Bellek sorunlarının hata ayıklaması:
- Memory Graph Debugger: Xcode'da nesneler arasındaki bağlantıları görselleştirir ve döngüleri tespit eder.
- Instruments (Allocations, Leaks): Bellek tahsisi ve serbest bırakmayı izler, sızıntıları tespit eder.