Middle+
Capture siyahısında həmişə weak və ya unowned istifadə edilməlidir?
sobes.tech Süni İntellekt
AI-dan cavab
Xeyr, həmişə deyil.
Weak və unowned, bağlamalarda güclü əlaqə dövrələrinin (retain cycles) qarşısını almaq üçün istifadə olunur, burada bağlama obyektə güclü əlaqə saxlayır və obyekt də öz növbəsində bağlamaya güclü əlaqə saxlayır.
weak və ya unowned istifadə etmək lazımdır, əgər bağlama güclü əlaqə saxlayan self və ya başqa bir referans tipini ələ keçirirsə və güclü əlaqə dövrəsinin yaranma ehtimalı varsa.
weak/unowned istifadə edilməməli olan hallar:
- Bağlama dəyər tiplərini (struktur, enumerasiya, tuple) ələ keçirir. Onlar ələ keçirildikdə kopyalanır və güclü əlaqə dövrələri yaranmır.
- Bağlama referans tipini ələ keçirir, lakin iki tərəfli güclü əlaqə yoxdur. Məsələn, bağlama lokal olaraq metod daxilində yaradılır və ona istinad edən obyekt tərəfindən saxlanmır.
- Bağlama qısa ömürlüdür və ona istinad edən obyekt sərbəst buraxılmadan əvvəl icra olunacaq. Məsələn, tamamlayıcı (Completion Handler) kimi metod daxilində ötürülən bağlama və dərhal icra olunur.
weak və unowned arasında seçim:
weak: istifadə olunur, əgər ələ keçirilmiş obyekt hər zamannilola bilər və ya ola bilər. İstinad opsionaldır (ObjectType?). İstifadə etməzdən əvvəlnilyoxlaması tələb olunur.unowned: istifadə olunur, əgər məlumdur ki, ələ keçirilmiş obyekt həmişə bağlamanın icrası zamanı mövcuddur. İstinad qeyri-opsionaldır (ObjectType).nilyoxlaması tələb olunmur.unownedistifadə edərkən obyektnilolarsa, bu, işləmə zamanı xətaya səbəb olar (runtime error).
// Nümunə, weak/unowned lazım deyil (struktur ələ keçirilməsi)
struct MyStruct {
var value: Int
}
let myStruct = MyStruct(value: 10)
let closure = {
print(myStruct.value) // myStruct kopyalanır
}
closure()
// Nümunə, weak/unowned lazım deyil (lokal bağlama)
class MyClass {
func doSomething() {
let localValue = 5
let localClosure = {
print(self.description) // self ələ keçirilir, amma MyClass saxlanmır
}
localClosure()
}
var description: String {
return "MyClass nümunəsi"
}
}
let myObject = MyClass()
myObject.doSomething()
// Nümunə, weak lazım (mümkün `nil`)
class AsyncOperation {
var completionHandler: (() -> Void)?
func performOperation() {
DispatchQueue.global().async {
print("Əməliyyat tamamlandı")
self.completionHandler?()
}
}
deinit {
print("AsyncOperation sərbəst buraxıldı")
}
}
class ViewController {
var op: AsyncOperation?
func setupOperation() {
op = AsyncOperation()
op?.completionHandler = { [weak self] in
guard let self = self else { return }
print("Tamamlama handleri ViewController-də: \(self)")
}
}
deinit {
print("ViewController sərbəst buraxıldı")
}
}
// Nümunə, unowned lazım (müəyyən ki, mövcuddur)
class Button {
var action: (() -> Void)?
func tap() {
action?()
}
deinit {
print("Button sərbəst buraxıldı")
}
}
class ViewControllerWithButton {
var button: Button
init() {
button = Button()
button.action = { [unowned self] in
print("Button vuruldu in ViewControllerWithButton: \(self)")
}
}
deinit {
print("ViewControllerWithButton sərbəst buraxıldı")
}
}