Unowned Reference (gazdátlan referencia) — egy nem birtokló referencia Swiftben, amely nem növeli az objektum retain count-ját, és a weak-től eltérően nem állítódik nil-ra a felszabadítása után. A Apple Swift Language Guide, 2026 szerint unowned akkor alkalmazandó, ha garantált, hogy az objektum legalább addig él, mint a rá hivatkozó objektum. A Weak Reference-től eltérően az unowned nem igényel unwrap-ot — ez egy non-optional típus, ami tisztábbá teszi a kódot, de a fejlesztőre hárítja az élettartam-garancia felelősségét.
Főbb pontok
Unowned Reference — egy nem birtokló referencia egy objektumra az ARC-ben, amely nem növeli annak retain count-ját. A weak-től eltérően az unowned nem nullázódik az objektum deallokációja után: továbbra is arra a memóriaterületre mutat, amely már felszabadításra került. Egy ilyen referencia elérése runtime crash-t okoz EXC_BAD_ACCESS-szel.
A „gazdátlan” kifejezés a szemantikát tükrözi: az objektum létezik, de senki nem felelős az élettartamáért. A fejlesztő kifejezetten kijelenti: „garantálom, hogy ez az objektum élni fog, amíg hivatkozom rá”. A fordító nem ellenőrzi ezt a garanciát — ez egy szerződés a fejlesztő szintjén.
A Swift.org Documentation, 2026 szerint az unowned referenciák előnyösebbek a weak-nél a garantált élettartamú forgatókönyvekben, mert: nem igényelnek opcionális típust (tisztább kód), nem igényelnek unwrap-ot (kevesebb force-unwrap vagy guard let), és nincs overhead-jük a zeroing weak-tábla karbantartására. Azonban a szerződés bármilyen megsértése — crash.
Swiftben az unowned referenciák a unowned kulcsszóval deklarálódnak a let vagy var előtt. A weak-től eltérően az unowned lehet let és var is, és nem igényel opcionális típust. Ez a tulajdonság teszi az unowned-ot kényelmessé azon referenciák számára, amelyek a tartomány logikája szerint nem lehetnek nil.
class Country {
let name: String
var capital: City! // inicializálás után lesz beállítva
init(name: String) { self.name = name }
}
class City {
let name: String
unowned let country: Country // unowned let — élet garancia
init(name: String, country: Country) {
self.name = name
self.country = country
}
}
// Használat
let france = Country(name: "France")
let paris = City(name: "Paris", country: france)
france.capital = paris
// Country → City (strong), City → Country (unowned) — nincs retain cycle
Ebben a példában City unowned let country — a város nem létezhet ország nélkül. Ha az ország eltűnik, a város (és a referencia) értelmét veszti. Szemantikailag ez ideális eset az unowned számára: élettartam-garancia létezik, optional nem szükséges, retain cycle nem keletkezik.
Az unowned var megengedett, de ritkábban fordul elő. Akkor használatos, ha a referencia helyettesíthető (pl. egy gyermek másik szülőhöz csatolása). A helyettesítéskor a régi objektum felszabadítása a külső tulajdonos felelőssége.
A Swift 5.0+ verzióban támogatást kapott az unowned optional (unowned let x: Type?). Ez egy kompromisszum: az unowned garantálja, hogy ha a referencia nem nil, az objektum él. A felszabadítási viselkedés — crash, mint a szokásos unowned esetében.
A választás az unowned és weak között — gyakori döntés a Swift architektúra tervezésekor. Vizsgáljuk meg a kritériumokat és ajánlásokat minden esetre.
| Kritérium | Weak | Unowned |
|---|---|---|
| Optional | Igen (Type?) | Nem (Type) |
| Nullázás deallokációkor | Auto nil-ra | Nem (lógó mutató kockázata) |
| Típus (let/var) | Csak var | let vagy var |
| Teljesítmény | Weak-tábla overhead | Minimális (egyszerű mutató) |
| Biztonság | Biztonságos (nil ellenőrzött) | EXC_BAD_ACCESS kockázat |
| Élettartam-garancia | Nem szükséges | Kifejezett garancia szükséges |
Használj weak-et, ha a legkisebb kétség is felmerül az objektum élettartamával kapcsolatban. A weak biztonságos, érthető és nem igényel bizonyítékot. Használj unowned-ot csak akkor, ha kizártad az összes olyan forgatókönyvet, amelyben az objektum korábban felszabadulhat. Tipikus esetek: gyermek, amely nem létezik szülő nélkül; szinkron végrehajtású lezárás; objektumra hivatkozás az init metódusán belül.
Az Airbnb Swift Style Guide, 2025 szerint nagy kódbázisokban ajánlott alapértelmezetten weak-et használni, unowned-ot pedig csak kifejezett megjegyzéssel, amely magyarázza az élettartam-garanciát. Ez csökkenti a nem nyilvánvaló crashek kockázatát refaktoráláskor.
A lezárások (closures) — a második leggyakoribb forgatókönyv az unowned használatára a parent-child kapcsolatok után. A capture list [unowned self] akkor alkalmazandó, ha self garantáltan tovább él, mint a lezárás. Vizsgáljuk meg a helyes és helytelen forgatókönyveket.
Szinkron lezárások — sorted, filter, map. Azonnal végrehajtódnak az aktuális szálban, self biztosan él. Az unowned-del való capture list itt elfogadható és tisztább kódot ad.
class DataProcessor {
var items: [Int] = [3, 1, 4, 1, 5]
func processSorted() {
// unowned self — sorted szinkron végrehajtódik, self garantáltan él
let sorted = items.sorted { [unowned self] a, b in
return self.customCompare(a, b)
}
}
func customCompare(_ a: Int, _ b: Int) -> Bool { return a < b }
}
Aszinkron lezárások — késleltetéssel, hálózati kérésekkel, animációkkal. Self felszabadulhat a lezárás elhelyezése és végrehajtása között. Itt unowned self → crash. Használj [weak self]-et.
class NetworkLoader {
func loadData() {
// VESZÉLYES: unowned self aszinkron lezárásban
URLSession.shared.dataTask(with: url) { [unowned self] data, _, _ in
self.handleResponse(data) // CRASH ha self felszabadításra került
}.resume()
}
func handleResponse(_ data: Data?) { }
// HELYES: weak self + guard
func loadDataSafe() {
URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in
guard let self else { return }
self.handleResponse(data)
}.resume()
}
}
Jegyezd meg a szabályt: unowned self — csak azonnal végrehajtódó szinkron lezárásokhoz. Aszinkronhoz — mindig weak self + guard let. Kivétel: ha kifejezetten tartasz egy referenciát az objektumra a lezárás befejezéséig (pl. egy erős capture eltárolásával egy másik változóban).
Az unowned — egy erőteljes, de veszélyes eszköz. Vizsgáljuk meg azokat a valós forgatókönyveket, ahol az unowned crash-hez vezethet, és a kockázat minimalizálásának módszereit.
Az unowned fő kockázata — az üzleti logika olyan megváltozása, amely miatt az élettartam-garancia már nem teljesül. A fejlesztő refaktorálja a kódot: megváltoztatja a tulajdonjogot, késleltetett felszabadítást vezet be, gyorsítótárat ad hozzá — és az unowned referencia időzített bombává válik. A fordító nem figyelmeztet — csak crash a felhasználó eszközén.
Javaslat: használj unowned-ot csak akkor, ha az élettartam-garancia nyilvánvaló és dokumentált. Adj megjegyzést minden unowned-hoz: miért biztonságos ez a referencia és milyen körülmények között sérülhet.
UIKit — fokozott kockázatú zóna az unowned számára. A ViewController bármikor felszabadulhat navigáció (pop, dismiss), memóriából való kiürítés, orientációváltás során. Ha egy ViewController-t unowned self-fel adsz át egy lezárásnak — a háttérből való visszatéréskor vagy animáció végén self nil lehet.
Az unowned használatakor a kockázat csökkentése érdekében kövesd ezeket a szabályokat:
// Példa: dokumentált unowned referencia explicit indoklással
class InvoiceLineItem {
let productName: String
let price: Decimal
// unowned Invoice — InvoiceLineItem nem létezhet Invoice nélkül.
// Invoice létrehozza az Item-et és törli azt saját törlésekor.
// Garancia: Invoice legalább olyan sokáig él, mint Item.
unowned let invoice: Invoice
init(productName: String, price: Decimal, invoice: Invoice) {
self.productName = productName
self.price = price
self.invoice = invoice
}
}
// Ez erős garancia: Invoice törli az összes Item-et deinit-ben.
// garancia megsértése = üzleti logikai hiba, amelyet javítani kell.
A garanciák dokumentálása — szakmai szabvány. Nagy projektekben (Airbnb, Uber) a code review minden unowned indoklását megköveteli. Ha a garancia nem nyilvánvaló — használj weak-et. Az unowned-hoz írt megjegyzés segít a jövőbeli fejlesztőknek megérteni, miért nincs itt weak, és milyen körülmények törhetik meg a garanciát.
Gyakran Ismételt Kérdések
Runtime crash EXC_BAD_ACCESS-szel. A Swift nem ellenőrzi az unowned referencia érvényességét eléréskor — ez csak egy „nyers” mutató. Ha az objektum felszabadításra került, a memória felülíródott, és az elérés crash-sel végződik. Ez egy el nem kapható kivétel (nem try-catch).
Igen, ha a protokoll örököl az AnyObject-tól. Az unowned minden referenciatípussal működik: osztályok, AnyObject protokollok, Objective-C objektumok. Az értéktípusok (struct, enum) nem támogatják az unowned-ot, mert nem vesznek részt az ARC-ben.
Amikor az élettartam-garancia abszolút és nyilvánvaló — az unowned biztonságosabb a tervezés szempontjából: nem igényel unwrap-ot, nem lehet nil, nem maszkol hibákat. Ha az objektum nem létezhet szülő nélkül, az unowned ezt kifejezett szerződéssé teszi, míg a weak elhomályosítja a garanciát.
Igen: az unowned gyorsabb, mert nem igényel hozzáférést a runtime weak-táblához a nullázáshoz. A legtöbb alkalmazásban a különbség nem érezhető, de milliós elérésszámú, nagy terhelésű forgatókönyvekben az unowned 10–20%-kal gyorsabb lehet olvasáskor.
Refaktorálás — az unowned fő veszélye. Az objektum élettartamának megváltozása (gyorsítótárazás, aszinkron műveletek, újrafelhasználás) megsértheti a garanciát. A fordító nem figyelmeztet. Megoldás: válts weak-re architektúraváltáskor, vagy adj hozzá figyelmeztető megjegyzést.
Összefoglaló
unowned let vagy unowned var; lehet non-optional és optional (Swift 5.0+)Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is