Unowned Reference (sahipsiz referans), Swift'te nesnenin retain count'unu artırmayan ve weak'in aksine, nesne serbest bırakıldıktan sonra nil olarak ayarlanmayan bir sahip olmayan referanstır. Apple Swift Language Guide, 2026'ya göre unowned, nesnenin en az onu referans alan nesne kadar yaşadığı garanti edildiğinde kullanılır. Weak Reference'ın aksine unowned, unwrap gerektirmez — bu opsiyonel olmayan bir türdür, kodu daha temiz yapar ancak yaşam süresi garantisi sorumluluğunu geliştiriciye yükler.
Kilit Noktalar
Unowned Reference, ARC'de bir nesneye retain count'unu artırmayan sahip olmayan bir referanstır. Weak'in aksine, unowned referans nesnenin serbest bırakılmasından sonra sıfırlanmaz: zaten serbest bırakılmış belleği işaret etmeye devam eder. Böyle bir referansa erişmek, EXC_BAD_ACCESS ile çalışma zamanı çökmesine neden olur.
“Sahipsiz” terimi anlambilimi yansıtır: nesne vardır, ancak yaşam süresinden kimse sorumlu değildir. Geliştirici açıkça beyan eder: “Bu nesnenin, ona referans verdiğim sürece canlı kalacağını garanti ediyorum.” Derleyici bu garantiyi doğrulamaz — bu geliştirici düzeyinde bir sözleşmedir.
Swift.org Documentation, 2026'ya göre, garantili yaşam süresi olan senaryolarda unowned referanslar weak'e tercih edilir çünkü: opsiyonel tür gerektirmezler (daha temiz kod), unwrap gerektirmezler (daha az force-unwrap veya guard let) ve sıfırlama için weak tablosu bakımının ek yükü yoktur. Ancak, sözleşmenin herhangi bir ihlali çökmeyle sonuçlanır.
Swift'te unowned referanslar, let veya var'dan önce unowned anahtar kelimesiyle bildirilir. Weak'in aksine, unowned hem let hem de var olabilir ve opsiyonel bir tür gerektirmez. Bu özellik, unowned'ı alan mantığıyla nil olamayacak referanslar için kullanışlı hale getirir.
class Country {
let name: String
var capital: City! // başlatmadan sonra ayarlanacak
init(name: String) { self.name = name }
}
class City {
let name: String
unowned let country: Country // ✅ unowned let — yaşam süresi garantisi
init(name: String, country: Country) {
self.name = name
self.country = country
}
}
// Kullanım
let france = Country(name: "France")
let paris = City(name: "Paris", country: france)
france.capital = paris
// ✅ Country → City (strong), City → Country (unowned) — retain cycle yok
Bu örnekte, City unowned let country — bir şehir ülke olmadan var olamaz. Ülke ortadan kaybolursa, şehir (ve referans) anlamını kaybeder. Anlambilimsel olarak, bu unowned için ideal bir durumdur: yaşam süresi garantisi vardır, opsiyonel gerekmez, retain cycle oluşmaz.
unowned var izin verilir ancak daha az yaygındır. Referansın değiştirilebildiği durumlarda kullanılır (örneğin, bir çocuğu farklı bir ebeveyne yeniden bağlama). Yeniden atamada, eski nesnenin serbest bırakılması dış sahibin sorumluluğundadır.
Swift 5.0+'da, unowned opsiyonel (unowned let x: Type?) desteği tanıtıldı. Bu bir uzlaşmadır: unowned, referans nil değilse nesnenin canlı olduğunu garanti eder. Serbest bırakıldığında davranış, normal unowned'da olduğu gibi çökmedir.
unowned ve weak arasındaki seçim, Swift mimarisi tasarlarken sık yapılan kararlardan biridir. Her durum için kriterleri ve önerileri inceleyelim.
| Kriter | Weak | Unowned |
|---|---|---|
| Opsiyonel | Evet (Type?) | Hayır (Type) |
| Serbest bırakmada sıfırlama | Otomatik olarak nil | Hayır (sarkan işaretçi riski) |
| Tür (let/var) | Sadece var | let veya var |
| Performans | Weak tablosu ek yükü | Minimum (basit işaretçi) |
| Güvenlik | Güvenli (nil kontrol edilir) | EXC_BAD_ACCESS riski |
| Yaşam süresi garantisi | Gerekmez | Açık garanti gerekli |
Weak kullanın eğer nesnenin yaşam süresi hakkında en ufak bir şüphe varsa. Weak güvenlidir, açıktır ve kanıt gerektirmez. Unowned kullanın yalnızca nesnenin daha önce serbest bırakılabileceği tüm senaryoları eleyebildiğinizde. Tipik durumlar: ebeveyn olmadan var olamayan çocuk; eşzamanlı olarak yürütülen closure; kendi başlatıcısı içindeki bir nesneye erişim.
Airbnb Swift Style Guide, 2025'e göre, büyük kod tabanlarında varsayılan olarak weak kullanılması ve unowned'ın yalnızca yaşam süresi garantisini açıklayan açık bir yorumla kullanılması önerilir. Bu, yeniden düzenleme sırasında belirgin olmayan çökmelerin riskini azaltır.
Closure'lar, ebeveyn-çocuk ilişkilerinden sonra unowned için ikinci en sık kullanım durumudur. Yakalama listesi [unowned self], self'in closure'dan daha uzun yaşayacağı garanti edildiğinde kullanılır. Doğru ve yanlış senaryoları inceleyelim.
Eşzamanlı closure'lar — sorted, filter, map. Bunlar mevcut iş parçacığında hemen yürütülür, self kesinlikle canlıdır. unowned ile yakalama listesi burada kabul edilebilir ve daha temiz kod sağlar.
class DataProcessor {
var items: [Int] = [3, 1, 4, 1, 5]
func processSorted() {
// ✅ unowned self — sorted eşzamanlı olarak yürütülür, self garantili olarak canlı
let sorted = items.sorted { [unowned self] a, b in
return self.customCompare(a, b)
}
}
func customCompare(_ a: Int, _ b: Int) -> Bool { return a < b }
}
Eşzamansız closure'lar — gecikmeler, ağ istekleri, animasyonlar ile. Self, closure'un planlanması ve yürütülmesi arasında serbest bırakılabilir. Burada unowned self çökmeye yol açar. [weak self] kullanın.
class NetworkLoader {
func loadData() {
// ❌ TEHLİKELİ: eşzamansız closure'da unowned self
URLSession.shared.dataTask(with: url) { [unowned self] data, _, _ in
self.handleResponse(data) // self serbest bırakılırsa ÇÖKME
}.resume()
}
func handleResponse(_ data: Data?) { }
// ✅ DOĞRU: weak self + guard
func loadDataSafe() {
URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in
guard let self else { return }
self.handleResponse(data)
}.resume()
}
}
Kuralı hatırlayın: unowned self — yalnızca hemen yürütülen eşzamanlı closure'lar için. Eşzamansız closure'lar için her zaman weak self + guard let kullanın. İstisna: closure tamamlanana kadar nesneye açıkça bir referans tutuyorsanız (örneğin, başka bir değişkende güçlü bir referans tutarak).
Unowned güçlü ancak tehlikeli bir araçtır. unowned'ın çökmelere yol açabileceği gerçek dünya senaryolarını ve riski en aza indirme yöntemlerini inceleyelim.
unowned'ın ana riski, yaşam süresi garantisini geçersiz kılan iş mantığındaki bir değişikliktir. Bir geliştirici kodu yeniden düzenler: sahipliği değiştirir, ertelenmiş serbest bırakma getirir, önbellekleme ekler — ve unowned referansı bir saatli bomba haline gelir. Derleyici uyarmaz — yalnızca kullanıcının cihazında çökme olur.
Öneri: unowned'ı yalnızca yaşam süresi garantisi açık ve belgelenmiş olduğunda kullanın. Her unowned'a bir yorum ekleyin: bu referans neden güvenli ve hangi koşullar altında ihlal edilebilir.
UIKit, unowned için yüksek riskli bir alandır. Bir ViewController, gezinme (pop, dismiss), bellek boşaltma veya yön değişiklikleri sırasında her an serbest bırakılabilir. Bir ViewController'ı unowned self ile bir closure'a aktarırsanız, arka plandan dönerken veya animasyon tamamlandığında self nil olabilir.
unowned kullanırken riski azaltmak için şu kuralları izleyin:
// Örnek: açık gerekçeyle belgelenmiş unowned referansı
class InvoiceLineItem {
let productName: String
let price: Decimal
// unowned Invoice — InvoiceLineItem, Invoice olmadan var olamaz.
// Invoice, Item oluşturur ve silindiğinde onu kaldırır.
// Garanti: Invoice, Item kadar en az onun kadar yaşar.
unowned let invoice: Invoice
init(productName: String, price: Decimal, invoice: Invoice) {
self.productName = productName
self.price = price
self.invoice = invoice
}
}
// Bu güçlü bir garantidir: Invoice, deinit'te tüm Item'ları kaldırır.
// garantiyi ihlal etmek = düzeltilmesi gereken bir iş mantığı hatası.
Garantileri belgelemek bir profesyonel standarttır. Büyük projelerde (Airbnb, Uber), kod incelemesi her unowned için gerekçe talep eder. Garanti açık değilse, weak kullanın. unowned hakkındaki bir yorum, gelecekteki geliştiricilerin neden burada weak kullanılmadığını ve hangi koşulların garantiyi bozabileceğini anlamasına yardımcı olur.
Sıkça Sorulan Sorular
Çalışma zamanı çökmesi (EXC_BAD_ACCESS). Swift, erişim sırasında unowned referansın geçerliliğini kontrol etmez — bu sadece “ham” bir işaretçidir. Nesne serbest bırakılırsa, bellek üzerine yazılır ve ona erişmek ölümcül şekilde sonlanır. Bu yakalanamaz bir istisnadır (try-catch değil).
Evet, protokol AnyObject'ten miras alıyorsa. Unowned tüm referans türleriyle çalışır: sınıflar, AnyObject protokolleri, Objective-C nesneleri. Değer türleri (struct, enum) ARC'ye katılmadıkları için unowned'ı desteklemez.
Yaşam süresi garantisi mutlak ve açık olduğunda — unowned tasarım açısından daha güvenlidir: unwrap gerektirmez, nil olamaz ve hataları gizlemez. Bir nesne ebeveyn olmadan var olamıyorsa, unowned bunu açık bir sözleşme haline getirirken, weak garantiyi bulanıklaştırır.
Evet: unowned daha hızlıdır çünkü sıfırlama için çalışma zamanında weak tablosuna erişim gerektirmez. Çoğu uygulamada fark hissedilmez, ancak milyonlarca erişimli yüksek yük senaryolarında unowned okumada %10–20 daha hızlı olabilir.
Yeniden düzenleme unowned için ana tehlikedir. Nesnenin yaşam süresini değiştirmek (önbellekleme, eşzamansız işlemler, yeniden kullanım) garantiyi bozabilir. Derleyici uyarmaz. Çözüm: mimariyi değiştirirken weak'e geçin veya bir uyarı yorumu ekleyin.
Özet
unowned let veya unowned var; opsiyonel olmayan ve opsiyonel (Swift 5.0+) olabilirAnahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun