Unowned Reference (ägarlös referens) — är en icke-ägande referens i Swift som inte ökar retain count för ett objekt och, till skillnad från weak, inte sätts till nil efter att objektet frigjorts. Enligt Apple Swift Language Guide, 2026 används unowned när det är garanterat att objektet lever minst lika länge som det objekt som refererar till det. Till skillnad från Weak Reference kräver unowned ingen unwrap — det är en non-optional typ, vilket gör koden renare, men lägger ansvaret för livslängdsgarantin på utvecklaren.
Huvudpunkter
Unowned Reference — är en icke-ägande referens till ett objekt i ARC som inte ökar dess retain count. Till skillnad från weak nollställs inte unowned efter objektets deallokering: den fortsätter att peka på det minnesområde som redan har frigjorts. Åtkomst till en sådan referens orsakar en runtime-krasch med EXC_BAD_ACCESS.
Termen “ägarlös” återspeglar semantiken: objektet finns, men ingen är ansvarig för dess livslängd. Utvecklaren förklarar uttryckligen: “jag garanterar att detta objekt kommer att leva så länge jag refererar till det”. Kompilatorn kontrollerar inte denna garanti — det är ett kontrakt på utvecklarnivå.
Enligt Swift.org Documentation, 2026 föredras unowned-referenser framför weak i scenarier med garanterad livslängd eftersom de: inte kräver en optionell typ (renare kod), inte kräver unwrap (mindre force-unwrap eller guard let) och har ingen overhead för att underhålla en zeroing weak-tabell. Men varje brott mot kontraktet — krasch.
I Swift deklareras unowned-referenser med nyckelordet unowned före let eller var. Till skillnad från weak kan unowned vara både let och var och kräver ingen optionell typ. Denna egenskap gör unowned bekvämt för referenser som enligt domänlogiken inte kan vara nil.
class Country {
let name: String
var capital: City! // kommer att ställas in efter initiering
init(name: String) { self.name = name }
}
class City {
let name: String
unowned let country: Country // unowned let — livsgaranti
init(name: String, country: Country) {
self.name = name
self.country = country
}
}
// Användning
let france = Country(name: "France")
let paris = City(name: "Paris", country: france)
france.capital = paris
// Country → City (strong), City → Country (unowned) — ingen retain cycle
I detta exempel City unowned let country — staden kan inte existera utan land. Om landet försvinner förlorar staden (och referensen) sin mening. Semantiskt är detta ett idealiskt fall för unowned: livslängdsgaranti finns, optional behövs inte, retain cycle uppstår inte.
unowned var är tillåtet men förekommer mer sällan. Används när referensen kan ersättas (t.ex. återkoppling av ett barn till en annan förälder). Vid ersättning är frigörandet av det gamla objektet den externa ägarens ansvar.
I Swift 5.0+ lades stöd för unowned optional till (unowned let x: Type?). Detta är en kompromiss: unowned garanterar att om referensen inte är nil, lever objektet. Beteende vid frigöring — krasch, som med vanlig unowned.
Valet mellan unowned och weak — ett av de vanliga besluten vid design av Swift-arkitektur. Låt oss titta på kriterierna och rekommendationerna för varje fall.
| Kriterium | Weak | Unowned |
|---|---|---|
| Optional | Ja (Type?) | Nej (Type) |
| Nollställning vid deallokering | Auto till nil | Nej (risk för dinglande pekare) |
| Typ (let/var) | Endast var | let eller var |
| Prestanda | Overhead för weak-tabell | Minimal (enkel pekare) |
| Säkerhet | Säkert (nil kontrolleras) | Risk för EXC_BAD_ACCESS |
| Livslängdsgaranti | Krävs inte | Kräver uttrycklig garanti |
Använd weak om det finns minsta tvivel om objektets livslängd. Weak är säkert, förståeligt och kräver inga bevis. Använd unowned endast när du har uteslutit alla scenarier där objektet skulle kunna frigöras tidigare. Typiska fall: barn som inte existerar utan förälder; closure som körs synkront; referens till ett objekt inom dess initierare.
Enligt Airbnb Swift Style Guide, 2025 rekommenderas i stora kodbaser att använda weak som standard och unowned — endast med en uttrycklig kommentar som förklarar livslängdsgarantin. Detta minskar risken för oväntade krascher vid refactoring.
Closures — det näst vanligaste användningsscenariot för unowned efter parent-child-relationer. Capture list [unowned self] används när self garanterat lever längre än closuren. Låt oss titta på rätt och fel scenarier.
Synkrona closures — sorted, filter, map. De körs omedelbart i den aktuella tråden, self lever definitivt. Capture list med unowned är acceptabelt här och ger renare kod.
class DataProcessor {
var items: [Int] = [3, 1, 4, 1, 5]
func processSorted() {
// unowned self — sorted körs synkront, self garanterat levande
let sorted = items.sorted { [unowned self] a, b in
return self.customCompare(a, b)
}
}
func customCompare(_ a: Int, _ b: Int) -> Bool { return a < b }
}
Asynkrona closures — med fördröjning, nätverksförfrågningar, animationer. Self kan frigöras mellan placeringen av closuren och dess exekvering. Här unowned self → krasch. Använd [weak self].
class NetworkLoader {
func loadData() {
// FARLIGT: unowned self i asynkron closure
URLSession.shared.dataTask(with: url) { [unowned self] data, _, _ in
self.handleResponse(data) // CRASH om self har frigjorts
}.resume()
}
func handleResponse(_ data: Data?) { }
// RÄTT: weak self + guard
func loadDataSafe() {
URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in
guard let self else { return }
self.handleResponse(data)
}.resume()
}
}
Kom ihåg regeln: unowned self — endast för synkrona closures som körs omedelbart. För asynkrona — alltid weak self + guard let. Undantag: om du uttryckligen håller en referens till objektet tills closuren är klar (t.ex. genom att spara en stark capture i en annan variabel).
Unowned — ett kraftfullt men farligt verktyg. Låt oss titta på verkliga scenarier där unowned kan leda till krasch och metoder för riskminimering.
Den största risken med unowned — förändring av affärslogik som gör att livslängdsgarantin inte längre uppfylls. Utvecklaren refaktorar koden: ändrar ägande, inför fördröjd frigöring, lägger till cachning — och unowned-referensen förvandlas till en tidsinställd bomb. Kompilatorn varnar inte — bara krasch på användarens enhet.
Rekommendation: använd unowned endast när livslängdsgarantin är uppenbar och dokumenterad. Lägg till en kommentar till varje unowned: varför denna referens är säker och under vilka förhållanden den kan brytas.
UIKit — en zon med förhöjd risk för unowned. ViewController kan frigöras när som helst vid navigering (pop, dismiss), urladdning från minne, orienteringsändring. Om du skickar en ViewController till en closure med unowned self — vid återkomst från bakgrunden eller slutet av en animation kan self vara nil.
För att minska risken vid användning av unowned, följ dessa regler:
// Exempel: dokumenterad unowned referens med explicit motivering
class InvoiceLineItem {
let productName: String
let price: Decimal
// unowned Invoice — InvoiceLineItem kan inte existera utan Invoice.
// Invoice skapar Item och tar bort det vid sin egen borttagning.
// Garanti: Invoice lever minst lika länge som Item.
unowned let invoice: Invoice
init(productName: String, price: Decimal, invoice: Invoice) {
self.productName = productName
self.price = price
self.invoice = invoice
}
}
// Detta är en stark garanti: Invoice tar bort alla Item i deinit.
// brott mot garanti = bugg i affärslogik som måste åtgärdas.
Dokumentation av garantier — professionell standard. I stora projekt (Airbnb, Uber) kräver code review motivering för varje unowned. Om garantin inte är uppenbar — använd weak. Kommentaren till unowned hjälper framtida utvecklare att förstå varför här inte finns weak och vilka förhållanden som kan bryta garantin.
Vanliga frågor
Runtime-krasch med EXC_BAD_ACCESS. Swift kontrollerar inte giltigheten av unowned-referensen vid åtkomst — det är bara en “rå” pekare. Om objektet har frigjorts är minnet överskrivet och åtkomst till det slutar med en krasch. Detta är ett inte fångbart undantag (inte try-catch).
Ja, om protokollet ärver från AnyObject. Unowned fungerar med alla referenstyper: klasser, AnyObject-protokoll, Objective-C-objekt. Värdetyper (struct, enum) stöder inte unowned eftersom de inte deltar i ARC.
När livslängdsgarantin är absolut och uppenbar — unowned är säkrare ur designsynpunkt: kräver ingen unwrap, kan inte vara nil, döljer inte fel. Om ett objekt inte kan existera utan förälder gör unowned detta till ett uttryckligt kontrakt, medan weak suddar ut garantin.
Ja: unowned är snabbare eftersom det inte kräver åtkomst till runtime weak-tabellen för nollställning. I de flesta applikationer är skillnaden inte märkbar, men i högbelastade scenarier med miljontals åtkomster kan unowned vara 10–20% snabbare vid läsning.
Refactoring — den största faran för unowned. Förändring av objektets livslängd (cachning, asynkrona operationer, återanvändning) kan bryta garantin. Kompilatorn varnar inte. Lösning: migrera till weak vid arkitekturändring eller lägg till en varningskommentar.
Sammanfattning
unowned let eller unowned var; kan vara non-optional och optional (Swift 5.0+)Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också