Middle
გვითხარით iOS-ის მეხსიერების მართვის შესახებ.
sobes.tech AI
პასუხი AI-სგან
iOS автоматтык эс тутумду башкаруу үчүн ARC (Automatic Reference Counting) колдонуп жатат. ARC автоматтык түрдө объекттерди бошотот, алардын шилтемелери жок болгондо:
Негизги түшүнүктөр:
- Күчтүү шилтеме: Объекттин шилтемелер санын көбөйтөт. Объект бошотулбайт, эгерде ага күчтүү шилтемелер болсо.
- Слаб шилтеме: шилтеме санын көбөйтпөйт. Выкарыстылат күчтүү шилтемелердин циклин алдын алуу үчүн. Объектке шилтеме, ал бошотулушу мүмкүн. Эгер объект бошотулса, слаб шилтеме
nilболот. - Unowned шилтеме: слаб шилтеме сыяктуу, бирок объект бошотулганда
nilболбойт. Объекттин өмүрү бирдей же узак болсо колдонулат. Unowned шилтемеnilболбойт, жана эгер объект бошотулса, ката чыгат.
Күчтүү шилтемелер цикли (Retain Cycles): эки же андан көп объекттин бири-бирине күчтүү шилтемелери бар болсо, ал алардын бошотулушуна тоскоол болот. Бул weak же unowned шилтемелер менен чечилет.
Мисал:
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) ишке киришти")
}
deinit {
print("\(name) жыйынтыкталды")
}
}
class Apartment {
let unit: String
weak var tenant: Person? // Циклды алдын алуу үчүн слаб шилтеме
init(unit: String) {
self.unit = unit
print("Apartment \(unit) ишке киришти")
}
deinit {
print("Apartment \(unit) жыйынтыкталды")
}
}
var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john // Цикл пайда болот
john = nil
unit4A = nil
// Деструктор методдору чакырылбайт, циклдин натыйжасында
Чечүү: weak колдонуу:
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) ишке киришти")
}
deinit {
print("\(name) жыйынтыкталды")
}
}
class Apartment {
let unit: String
weak var tenant: Person? // Циклды алдын алуу үчүн слаб шилтеме
init(unit: String) {
self.unit = unit
print("Apartment \(unit) ишке киришти")
}
deinit {
print("Apartment \(unit) жыйынтыкталды")
}
}
var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil
unit4A = nil
// Эки объект да туура жыйынтыкталат
Unowned vs Weak:
weakколдон, эгер шилтемеnilболушу мүмкүн болсо (объект биринчи бошотулушу мүмкүн)unownedколдон, эгер шилтеме дайыма мааниге ээ болсо (объекттин өмүрү бирдей же узак)
Closure жана циклы шилтемелер:
Closure-лар объекттерге шилтемелерди захват кылышы мүмкүн, бул күчтүү циклы түзөт. Бул capture list аркылуу чечилет.
Мисал:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
[weak self] in // self-ди слаб шилтемеде захват кылуу
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) жыйынтыкталды")
}
}
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "салам, дүйнө")
print(paragraph!.asHTML())
paragraph = nil
// Объект жыйынтыкталды
Эстутумду түзөтүү:
- Memory Graph Debugger: Xcode ичинде объекттердин байланышын визуалдаштырып, циклы аныктайт.
- Instruments (Allocations, Leaks): Эстутумдун бөлүштүрүлүшү жана бошотулушун көзөмөлдөйт, унутулуп калган жерлерди табат.