Junior — Middle
Vai var rasties grūtības vai negaidīta uzvedība, ja klases iekšējais aizvērums piekļūst tās metodēm vai īpašībām?
sobes.tech AI
Atbilde no AI
Jā, izmantojot aizvērumus (closures) Swift klases ietvaros, var rasties grūtības, kas saistītas ar self noķeršanu un iespējamiem noturēšanas cikliem (retain cycles).
Ja aizvērums noķer self bez izmantošanas vājas ([weak self]) vai nenosauktas ([unowned self]) atsauces, tas var novest pie tā, ka klases instances netiks atbrīvotas no atmiņas, jo aizvērums uztur stipru atsauci uz self, un self var uzturēt aizvērumu.
Problēmas piemērs:
class MyClass {
var closure: (() -> Void)?
var value = 10
func setupClosure() {
closure = {
print(self.value) // noķer `self`
}
}
deinit {
print("MyClass ir atbrīvots")
}
}
var obj: MyClass? = MyClass()
obj?.setupClosure()
obj = nil // MyClass netiks atbrīvots, jo ir noturēšanas cikls
Lai izvairītos no tā, izmanto vājo atsauci:
closure = { [weak self] in
guard let self = self else { return }
print(self.value)
}
Tādēļ ir svarīgi rūpīgi pārvaldīt self noķeršanu klasēs, lai izvairītos no atmiņas noplūdēm un negaidītām uzvedībām.