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): Эстутумдун бөлүштүрүлүшү жана бошотулушун көзөмөлдөйт, унутулуп калган жерлерди табат.