Unowned Reference (eigenaarloze referentie) — is een niet-bezittende referentie in Swift die de retain count van een object niet verhoogt en, in tegenstelling tot weak, niet op nil wordt gezet na deallocatie. Volgens Apple Swift Language Guide, 2026 wordt unowned gebruikt wanneer gegarandeerd is dat het object minstens zo lang leeft als het ernaar verwijzende object. In tegenstelling tot Weak Reference vereist unowned geen unwrap — het is een non-optional type, wat de code schoner maakt, maar de verantwoordelijkheid voor de levensduurgarantie bij de ontwikkelaar legt.
Belangrijkste punten
Unowned Reference — is een niet-bezittende referentie naar een object in ARC die de retain count niet verhoogt. In tegenstelling tot weak wordt unowned niet gezeroïd na deallocatie: het blijft verwijzen naar het geheugengebied dat al is vrijgegeven. Toegang tot zo’n referentie veroorzaakt een runtime crash met EXC_BAD_ACCESS.
De term „eigenaarloos“ weerspiegelt de semantiek: het object bestaat, maar niemand is verantwoordelijk voor zijn levensduur. De ontwikkelaar verklaart expliciet: „ik garandeer dat dit object zal leven zolang ik ernaar verwijs“. De compiler controleert deze garantie niet — het is een contract op ontwikkelaarsniveau.
Volgens Swift.org Documentation, 2026 hebben unowned referenties de voorkeur boven weak in scenario’s met gegarandeerde levensduur omdat ze: geen optioneel type vereisen (schonere code), geen unwrap vereisen (minder force-unwrap of guard let) en geen overhead hebben voor het bijhouden van een zeroing weak-tabel. Echter, elke schending van het contract — crash.
In Swift worden unowned referenties gedeclareerd met het sleutelwoord unowned voor let of var. In tegenstelling tot weak kan unowned zowel let als var zijn en vereist het geen optioneel type. Deze eigenschap maakt unowned handig voor referenties die volgens de domeinlogica niet nil kunnen zijn.
class Country {
let name: String
var capital: City! // wordt ingesteld na initialisatie
init(name: String) { self.name = name }
}
class City {
let name: String
unowned let country: Country // unowned let — levensgarantie
init(name: String, country: Country) {
self.name = name
self.country = country
}
}
// Gebruik
let france = Country(name: "France")
let paris = City(name: "Paris", country: france)
france.capital = paris
// Country → City (strong), City → Country (unowned) — geen retain cycle
In dit voorbeeld City unowned let country — de stad kan niet bestaan zonder land. Als het land verdwijnt, verliezen de stad (en de referentie) hun betekenis. Semantisch is dit een ideaal geval voor unowned: levensduurgarantie bestaat, optional is niet nodig, retain cycle ontstaat niet.
unowned var is toegestaan maar komt minder vaak voor. Het wordt gebruikt wanneer de referentie kan worden vervangen (bijv. het opnieuw koppelen van een kind aan een andere ouder). Bij vervanging is het vrijgeven van het oude object de verantwoordelijkheid van de externe eigenaar.
In Swift 5.0+ is ondersteuning voor unowned optional toegevoegd (unowned let x: Type?). Dit is een compromis: unowned garandeert dat als de referentie niet nil is, het object leeft. Gedrag bij vrijgeven — crash, zoals bij gewone unowned.
De keuze tussen unowned en weak — een van de frequente beslissingen bij het ontwerpen van Swift-architectuur. Laten we de criteria en aanbevelingen voor elk geval bekijken.
| Criterium | Weak | Unowned |
|---|---|---|
| Optional | Ja (Type?) | Nee (Type) |
| Zeroing bij deallocatie | Auto naar nil | Nee (risico op hangende pointer) |
| Type (let/var) | Alleen var | let of var |
| Prestatie | Overhead voor weak-tabel | Minimaal (simpele pointer) |
| Veiligheid | Veilig (nil wordt gecontroleerd) | Risico EXC_BAD_ACCESS |
| Levensduurgarantie | Niet vereist | Expliciete garantie vereist |
Gebruik weak als er ook maar de geringste twijfel bestaat over de levensduur van het object. Weak is veilig, begrijpelijk en vereist geen bewijs. Gebruik unowned alleen wanneer u alle scenario’s hebt uitgesloten waarin het object eerder kan worden vrijgegeven. Typische gevallen: kind dat niet bestaat zonder ouder; closure die synchroon wordt uitgevoerd; verwijzing naar een object binnen zijn initialisator.
Volgens Airbnb Swift Style Guide, 2025 wordt in grote codebases aanbevolen om standaard weak te gebruiken en unowned — alleen met een expliciete opmerking die de levensduurgarantie uitlegt. Dit vermindert het risico op onvoorziene crashes bij refactoring.
Closures — het tweede meest voorkomende scenario voor unowned na parent-child relaties. Capture list [unowned self] wordt toegepast wanneer self gegarandeerd langer leeft dan de closure. Laten we de juiste en onjuiste scenario’s bekijken.
Synchrone closures — sorted, filter, map. Ze worden onmiddellijk in de huidige thread uitgevoerd, self is zeker levend. Capture list met unowned is hier acceptabel en geeft schonere code.
class DataProcessor {
var items: [Int] = [3, 1, 4, 1, 5]
func processSorted() {
// unowned self — sorted wordt synchroon uitgevoerd, self gegarandeerd levend
let sorted = items.sorted { [unowned self] a, b in
return self.customCompare(a, b)
}
}
func customCompare(_ a: Int, _ b: Int) -> Bool { return a < b }
}
Asynchrone closures — met vertraging, netwerkverzoeken, animaties. Self kan worden vrijgegeven tussen het plaatsen van de closure en de uitvoering ervan. Hier unowned self → crash. Gebruik [weak self].
class NetworkLoader {
func loadData() {
// GEVAARLIJK: unowned self in asynchrone closure
URLSession.shared.dataTask(with: url) { [unowned self] data, _, _ in
self.handleResponse(data) // CRASH als self is vrijgegeven
}.resume()
}
func handleResponse(_ data: Data?) { }
// JUIST: weak self + guard
func loadDataSafe() {
URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in
guard let self else { return }
self.handleResponse(data)
}.resume()
}
}
Onthoud de regel: unowned self — alleen voor synchrone closures die onmiddellijk worden uitgevoerd. Voor asynchrone — altijd weak self + guard let. Uitzondering: als u expliciet een referentie naar het object vasthoudt tot de closure is voltooid (bijv. door een sterke capture in een andere variabele te bewaren).
Unowned — een krachtig maar gevaarlijk hulpmiddel. Laten we de reële scenario’s bekijken waarin unowned kan leiden tot een crash en methoden voor risicominimalisatie.
Het grootste risico van unowned — wijziging van bedrijfslogica waardoor de levensduurgarantie niet langer geldt. De ontwikkelaar refactort de code: verandert eigendom, voert vertraagde vrijgave in, voegt caching toe — en de unowned referentie verandert in een tijdbom. De compiler waarschuwt niet — alleen een crash op het apparaat van de gebruiker.
Aanbeveling: gebruik unowned alleen wanneer de levensduurgarantie duidelijk en gedocumenteerd is. Voeg een opmerking toe bij elke unowned: waarom deze referentie veilig is en onder welke omstandigheden deze kan worden geschonden.
UIKit — een zone met verhoogd risico voor unowned. ViewController kan op elk moment worden vrijgegeven bij navigatie (pop, dismiss), uit geheugen worden geladen, oriëntatiewijziging. Als u een ViewController doorgeeft aan een closure met unowned self — bij terugkeer uit de achtergrond of aan het einde van een animatie kan self nil zijn.
Om het risico bij het gebruik van unowned te verminderen, volgt u deze regels:
// Voorbeeld: gedocumenteerde unowned referentie met expliciete rechtvaardiging
class InvoiceLineItem {
let productName: String
let price: Decimal
// unowned Invoice — InvoiceLineItem kan niet bestaan zonder Invoice.
// Invoice maakt Item aan en verwijdert het bij eigen verwijdering.
// Garantie: Invoice leeft minstens zo lang als Item.
unowned let invoice: Invoice
init(productName: String, price: Decimal, invoice: Invoice) {
self.productName = productName
self.price = price
self.invoice = invoice
}
}
// Dit is een sterke garantie: Invoice verwijdert alle Item in deinit.
// schending van garantie = bug in bedrijfslogica die gerepareerd moet worden.
Documentatie van garanties — professionele standaard. In grote projecten (Airbnb, Uber) vereist code review rechtvaardiging van elke unowned. Als de garantie niet duidelijk is — gebruik weak. Een opmerking bij unowned helpt toekomstige ontwikkelaars te begrijpen waarom hier geen weak is en welke omstandigheden de garantie kunnen breken.
Veelgestelde vragen
Runtime crash met EXC_BAD_ACCESS. Swift controleert de geldigheid van de unowned referentie niet bij toegang — het is slechts een „rauwe“ pointer. Als het object is vrijgegeven, is het geheugen overschreven en leidt toegang ertoe tot een crash. Dit is een niet-afvangbare uitzondering (geen try-catch).
Ja, als het protocol overerft van AnyObject. Unowned werkt met alle referentietypen: klassen, AnyObject-protocollen, Objective-C-objecten. Waardetypen (struct, enum) ondersteunen unowned niet omdat ze niet deelnemen aan ARC.
Wanneer de levensduurgarantie absoluut en duidelijk is — unowned is veiliger vanuit ontwerpperspectief: het vereist geen unwrap, kan niet nil zijn, maskeert geen fouten. Als een object niet kan bestaan zonder ouder, maakt unowned dit een expliciet contract, terwijl weak de garantie vervaagt.
Ja: unowned is sneller omdat het geen toegang tot de runtime weak-tabel nodig heeft voor zeroing. In de meeste applicaties is het verschil niet merkbaar, maar in zwaarbelaste scenario’s met miljoenen toegangen kan unowned 10–20% sneller zijn bij lezen.
Refactoring — het grootste gevaar voor unowned. Verandering van de levensduur van het object (caching, asynchrone bewerkingen, hergebruik) kan de garantie schenden. De compiler waarschuwt niet. Oplossing: migreer naar weak bij architectuurwijziging of voeg een waarschuwingsopmerking toe.
Samenvatting
unowned let of unowned var; kan non-optional en optional zijn (Swift 5.0+)We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.