Unowned Reference (reference bez vlastníka) — je nevlastnící reference ve Swift, která nezvyšuje retain count objektu a na rozdíl od weak se po uvolnění objektu nenastavuje na nil. Podle Apple Swift Language Guide, 2026 se unowned používá, když je zaručeno, že objekt žije alespoň tak dlouho jako objekt, který se na něj odkazuje. Na rozdíl od Weak Reference unowned nevyžaduje unwrap — je to non-optional typ, který dělá kód čistším, ale klade odpovědnost za záruku životnosti na vývojáře.
Hlavní body
Unowned Reference — je nevlastnící reference na objekt v ARC, která nezvyšuje jeho retain count. Na rozdíl od weak se unowned po dealokaci objektu nenuluje: nadále ukazuje na oblast paměti, která již byla uvolněna. Přístup k takové referenci způsobí runtime crash s EXC_BAD_ACCESS.
Termín „bez vlastníka” odráží sémantiku: objekt existuje, ale nikdo nenese odpovědnost za jeho životnost. Vývojář výslovně prohlašuje: „garantuji, že tento objekt bude žít, dokud se na něj odkazuji”. Kompilátor tuto záruku nekontroluje — je to kontrakt na úrovni vývojáře.
Podle Swift.org Documentation, 2026 jsou unowned reference preferovány před weak ve scénářích s garantovanou životností, protože: nevyžadují volitelný typ (čistší kód), nevyžadují unwrap (méně force-unwrap nebo guard let) a nemají režii na udržování zeroing weak tabulky. Nicméně jakékoli porušení kontraktu — crash.
Ve Swift se unowned reference deklarují klíčovým slovem unowned před let nebo var. Na rozdíl od weak může být unowned jak let, tak var a nevyžaduje volitelný typ. Tato vlastnost činí unowned vhodným pro reference, které podle doménové logiky nemohou být nil.
class Country {
let name: String
var capital: City! // bude nastaveno po inicializaci
init(name: String) { self.name = name }
}
class City {
let name: String
unowned let country: Country // unowned let — záruka života
init(name: String, country: Country) {
self.name = name
self.country = country
}
}
// Použití
let france = Country(name: "France")
let paris = City(name: "Paris", country: france)
france.capital = paris
// Country → City (strong), City → Country (unowned) — bez retain cycle
V tomto příkladu City unowned let country — město nemůže existovat bez země. Pokud země zmizí, město (a reference) ztratí smysl. Sémanticky je to ideální případ pro unowned: záruka životnosti existuje, optional není potřeba, retain cycle nevzniká.
unowned var je povoleno, ale vyskytuje se méně často. Používá se, když může být reference nahrazena (např. přepojení dítěte k jinému rodiči). Při nahrazení je uvolnění starého objektu odpovědností externího vlastníka.
V Swift 5.0+ byla přidána podpora pro unowned optional (unowned let x: Type?). To je kompromis: unowned zaručuje, že pokud reference není nil, objekt žije. Chování při uvolnění — crash, jako u běžného unowned.
Volba mezi unowned a weak — jedno z častých rozhodnutí při navrhování Swift architektury. Podívejme se na kritéria a doporučení pro každý případ.
| Kritérium | Weak | Unowned |
|---|---|---|
| Optional | Ano (Type?) | Ne (Type) |
| Nulování při dealokaci | Auto na nil | Ne (riziko visícího ukazatele) |
| Typ (let/var) | Pouze var | let nebo var |
| Výkon | Režie pro weak tabulku | Minimální (jednoduchý ukazatel) |
| Bezpečnost | Bezpečné (nil se kontroluje) | Riziko EXC_BAD_ACCESS |
| Záruka životnosti | Není vyžadována | Vyžaduje výslovnou záruku |
Použijte weak, pokud existuje byť jen sebemenší pochybnost o životnosti objektu. Weak je bezpečný, srozumitelný a nevyžaduje důkazy. Použijte unowned pouze když jste vyloučili všechny scénáře, při kterých by objekt mohl být uvolněn dříve. Typické případy: dítě, které neexistuje bez rodiče; uzávěrka, která se provádí synchronně; odkaz na objekt v rámci jeho inicializátoru.
Podle Airbnb Swift Style Guide, 2025 se ve velkých kódových základnách doporučuje používat weak standardně a unowned — pouze s výslovným komentářem vysvětlujícím záruku životnosti. To snižuje riziko neočekávaných crashů při refaktorování.
Uzávěrky (closures) — druhý nejčastější scénář použití unowned po parent-child vztazích. Capture list [unowned self] se používá, když je zaručeno, že self žije déle než uzávěrka. Podívejme se na správné a nesprávné scénáře.
Synchronní uzávěrky — sorted, filter, map. Provádějí se okamžitě v aktuálním vlákně, self určitě žije. Capture list s unowned je zde přijatelný a dává čistší kód.
class DataProcessor {
var items: [Int] = [3, 1, 4, 1, 5]
func processSorted() {
// unowned self — sorted se provádí synchronně, self zaručeně žije
let sorted = items.sorted { [unowned self] a, b in
return self.customCompare(a, b)
}
}
func customCompare(_ a: Int, _ b: Int) -> Bool { return a < b }
}
Asynchronní uzávěrky — se zpožděním, síťovými požadavky, animacemi. Self může být uvolněno mezi umístěním uzávěrky a jejím provedením. Zde unowned self → crash. Použijte [weak self].
class NetworkLoader {
func loadData() {
// NEBEZPEČNÉ: unowned self v asynchronním uzávěru
URLSession.shared.dataTask(with: url) { [unowned self] data, _, _ in
self.handleResponse(data) // CRASH pokud je self uvolněno
}.resume()
}
func handleResponse(_ data: Data?) { }
// SPRÁVNĚ: weak self + guard
func loadDataSafe() {
URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in
guard let self else { return }
self.handleResponse(data)
}.resume()
}
}
Zapamatujte si pravidlo: unowned self — pouze pro synchronní uzávěrky provádějící se okamžitě. Pro asynchronní — vždy weak self + guard let. Výjimka: pokud výslovně držíte referenci na objekt do dokončení uzávěrky (např. uložením silného capture do jiné proměnné).
Unowned — mocný, ale nebezpečný nástroj. Podívejme se na reálné scénáře, kde unowned může vést k crash, a metody minimalizace rizika.
Hlavní riziko unowned — změna obchodní logiky, při které záruka životnosti přestává platit. Vývojář refaktoruje kód: mění vlastnictví, zavádí odložené uvolňování, přidává cachování — a unowned reference se mění v časovanou bombu. Kompilátor nevaruje — pouze crash na zařízení uživatele.
Doporučení: používejte unowned pouze když je záruka životnosti zřejmá a zdokumentovaná. Přidejte komentář ke každému unowned: proč je tato reference bezpečná a za jakých podmínek může být porušena.
UIKit — zóna zvýšeného rizika pro unowned. ViewController může být uvolněn kdykoli při navigaci (pop, dismiss), uvolnění z paměti, změně orientace. Pokud předáte ViewController do uzávěrky s unowned self — při návratu z pozadí nebo dokončení animace může být self nil.
Pro snížení rizika při používání unowned dodržujte tato pravidla:
// Příklad: dokumentovaná unowned reference s explicitním odůvodněním
class InvoiceLineItem {
let productName: String
let price: Decimal
// unowned Invoice — InvoiceLineItem nemůže existovat bez Invoice.
// Invoice vytváří Item a maže jej při svém smazání.
// Záruka: Invoice žije nejméně tak dlouho jako Item.
unowned let invoice: Invoice
init(productName: String, price: Decimal, invoice: Invoice) {
self.productName = productName
self.price = price
self.invoice = invoice
}
}
// To je silná záruka: Invoice maže všechny Item v deinit.
// porušení záruky = chyba v obchodní logice, kterou je třeba opravit.
Dokumentování záruk — profesionální standard. Ve velkých projektech (Airbnb, Uber) code review vyžaduje odůvodnění každého unowned. Pokud záruka není zřejmá — použijte weak. Komentář k unowned pomáhá budoucím vývojářům pochopit, proč zde není weak a jaké podmínky mohou záruku porušit.
Často kladené otázky
Runtime crash s EXC_BAD_ACCESS. Swift nekontroluje platnost unowned reference při přístupu — je to jen „surový” ukazatel. Pokud byl objekt uvolněn, paměť je přepsána a přístup k ní končí crash. Toto je nezachytitelná výjimka (není try-catch).
Ano, pokud protokol dědí z AnyObject. Unowned funguje se všemi referenčními typy: třídy, protokoly AnyObject, Objective-C objekty. Hodnotové typy (struct, enum) nepodporují unowned, protože se neúčastní ARC.
Když je záruka životnosti absolutní a zřejmá — unowned je bezpečnější z hlediska návrhu: nevyžaduje unwrap, nemůže být nil, neskrývá chyby. Pokud objekt nemůže existovat bez rodiče, unowned z toho dělá výslovný kontrakt, zatímco weak záruku rozmazává.
Ano: unowned je rychlejší, protože nevyžaduje přístup k weak tabulce runtime pro nulování. Ve většině aplikací je rozdíl neznatelný, ale ve vysoce zatížených scénářích s miliony přístupů může být unowned o 10–20% rychlejší při čtení.
Refaktorování — hlavní nebezpečí pro unowned. Změna životnosti objektu (cachování, asynchronní operace, opětovné použití) může porušit záruku. Kompilátor nevaruje. Řešení: migrujte na weak při změně architektury nebo přidejte varovný komentář.
Shrnutí
unowned let nebo unowned var; může být non-optional a optional (Swift 5.0+)Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také