Middle+
Capture List'te her zaman weak veya unowned kullanmak gerekir mi?
sobes.tech yapay zeka
AI'dan gelen yanıt
Hayır, her zaman değil.
Weak ve unowned, closure'larda güçlü referans döngülerini (retain cycles) önlemek için kullanılır, bir closure bir nesneye güçlü referans tutarken ve nesne de aynı zamanda closure'a güçlü referans tutarken.
weak veya unowned kullanmak gerekirse, closure self veya başka bir referans tipi üzerinde güçlü referans tutar ve güçlü referans döngüsü olasılığı varsa.
weak/unowned kullanmaya gerek olmayan durumlar:
- Closure değer tipleri (yapılar, enumlar, tuple'lar) yakalar. Bunlar yakalama sırasında kopyalanır ve güçlü referans döngüleri oluşmaz.
- Closure, referans tipi yakalar, ancak iki yönlü güçlü referans döngüsü yoktur. Örneğin, closure yerel olarak bir metodun içinde oluşturulur ve referans aldığı nesnede saklanmaz.
- Closure kısa ömürlüdür ve ona referans verilen nesne serbest bırakılmadan önce çalıştırılır. Örneğin, hemen çalışan bir tamamlayıcı (completion handler) olarak geçirilen closure.
weak ve unowned arasındaki seçim:
weak: Yakalanan nesne, herhangi bir zamandanilolabilir, closure çalışmadan önce. Referans opsiyoneldir (ObjectType?). Kullanımdan öncenilkontrolü gerekir.unowned: Yakalanan nesne, her zaman closure çalışırken var olacağı biliniyor. Referans opsiyonsuzdur (ObjectType).nilkontrolü gerekmez.unownedilenilolan nesne kullanımı çalışma zamanında çökmesine neden olur.
// `weak`/`unowned` gerekmediği örnek (değer tipi yakalama)
struct MyStruct {
var value: Int
}
let myStruct = MyStruct(value: 10)
let closure = {
print(myStruct.value) // myStruct'in bir kopyasını yakalar
}
closure()
// `weak`/`unowned` gerekmediği örnek (yerel closure)
class MyClass {
func doSomething() {
let localValue = 5
let localClosure = {
print(self.description) // self yakalanır, ama closure MyClass'ta saklanmaz
}
localClosure()
}
var description: String {
return "Instance of MyClass"
}
}
let myObject = MyClass()
myObject.doSomething()
// `weak` gerekilen örnek (potansiyel nil)
class AsyncOperation {
var completionHandler: (() -> Void)?
func performOperation() {
// Asenkron çalışma simülasyonu
DispatchQueue.global().async {
print("Operation completed")
self.completionHandler?() // opsiyonel zincirleme
}
}
deinit {
print("AsyncOperation deinitialized")
}
}
class ViewController {
var op: AsyncOperation?
func setupOperation() {
op = AsyncOperation()
op?.completionHandler = { [weak self] in // weak self
guard let self = self else { return }
print("Completion handler in ViewController: \(self)")
}
}
deinit {
print("ViewController deinitialized")
}
}
// `unowned` gerekilen örnek (her zaman var)
class Button {
var action: (() -> Void)?
func tap() {
action?()
}
deinit {
print("Button deinitialized")
}
}
class ViewControllerWithButton {
var button: Button
init() {
button = Button()
button.action = { [unowned self] in // unowned self
print("Button tapped in ViewControllerWithButton: \(self)")
}
}
deinit {
print("ViewControllerWithButton deinitialized")
}
}