iOSтогу кармоо циклдери (retain cycles) эмне?
sobes.tech AI
AIден жооп
Кайталануу циклдары пайда болот, эгер эки же андан көп объект бири-бирине күчтүү шилтемелерге ээ болсо, бул "жабык чынжыр" түзөт. Натыйжада, ар бир объекттин шилтемелер санагычы нөлгө жетпейт жана ал ARC (Automatic Reference Counting) тарабынан бошотулбайт. Бул эс тутумдун агып кетишине алып келет, анткени объекттер колдонулбаса дагы эс тутумда калат.
Мисал:
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) ишке киришүүдө")
}
deinit {
print("\(name) бошотулууда")
}
}
class Apartment {
let unit: String
var tenant: Person?
init(unit: String) {
self.unit = unit
print("Apartment \(unit) ишке киришүүдө")
}
deinit {
print("Apartment \(unit) бошотулууда")
}
}
Бул мисалда, эгер Person күчтүү шилтемеге ээ болсо Apartmentка жана Apartment күчтүү шилтемеге ээ болсо Personга, анда бул объекттер бошотулгондо, алар өчүрүлбөйт, анткени алардын шилтемелер санагычтары нөлгө жетпейт.
Кайсы учурда кайталануучу циклдарды чечүү керек:
слабый (weak) же башкача (unowned) шилтемелерди колдонуу.
weak: Бул, байланышкан объектnilболушу мүмкүн болгон учурда колдонулат. шилтеме автоматтык түрдөnilболот, объект бошотулганда. Бул опционалдуу.unowned: Бул, байланышкан объекттин ошол же узак жашоо цикли бар экендигин билгенде колдонулат.nilболбойт.
Түзөтүлгөн мисал weak колдонуу менен:
Apartment классынын tenant шилтемесин алсызга өзгөртөлү:
class Apartment {
let unit: String
weak var tenant: Person? // weak колдонулуп жатат
init(unit: String) {
self.unit = unit
print("Apartment \(unit) ишке киришүүдө")
}
deinit {
print("Apartment \(unit) бошотулууда")
}
}
Эми, Person объекти бошотулганда, tenant шилтемеси автоматтык түрдө nil болот, бул кайталануучу циклды үзүп, Apartment да бошотулушуна мүмкүндүк берет.
weak жана unowned салыштыруу:
| Өзгөчөлүк | weak |
unowned |
|---|---|---|
| Шилтеменин түрү | Опционалдуу | Опционалдуу эмес |
nil болушу мүмкүнбү? |
Ооба, объект бошотулганда | Жок |
| Кайсы учурда колдонуу керек? | Объект nil болушу мүмкүн болсо |
Объект nil болбошу керек болсо |
| Аткаруу ылдамдыгы | Азырынча жайыраак, nil текшерүү үчүн |
Азырынча тезирээк |
Мындан тышкары, кайталануучу циклдар жабдууларда да пайда болушу мүмкүн.
Жабдуулар self жана же өзгөчөлүктөрдү камтыганда, ал күчтүү шилтемени түзө алат. Эгер бул объект ошондой эле күчтүү шилтемеге ээ болсо жабдууга (мисалы, өзгөчөлүк-жабдуусу же делегат аркылуу), анда цикл пайда болот.
Кайсы учурда кайталануучу циклдарды чечүү керек:
capture list колдонуу.
class SomeClass {
var value = 0
func doSomethingDelayed() {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in // capture list менен weak self
guard let self = self else { return } // `nil` текшерүү үчүн
self.value += 1
print("Кийинки мааниси \(self.value)")
}
}
}
Бул мисалда, [weak self] жабдуунун ичинде selfке алсыз шилтемени түзөт, бул кайталануучу циклдарды алдын алат.