Unowned Reference (referência não proprietária) é uma referência não detentora em Swift que não aumenta o retain count do objeto e, ao contrário de weak, não é definida como nil após a liberação do objeto. De acordo com Apple Swift Language Guide, 2026, unowned é usado quando é garantido que o objeto vive pelo menos tanto quanto o objeto que o referencia. Ao contrário de Weak Reference, unowned não requer unwrap — é um tipo não opcional, o que torna o código mais limpo, mas coloca a responsabilidade no desenvolvedor de garantir o tempo de vida.
Principais Pontos
Unowned Reference é uma referência não proprietária a um objeto em ARC que não aumenta seu retain count. Ao contrário de weak, uma referência unowned não é zerada após a desalocação do objeto: ela continua apontando para memória que já foi liberada. Acessar tal referência causa um crash em tempo de execução com EXC_BAD_ACCESS.
O termo “não proprietária” reflete a semântica: o objeto existe, mas ninguém é responsável por seu tempo de vida. O desenvolvedor declara explicitamente: “garanto que este objeto estará vivo enquanto eu o referenciar.” O compilador não verifica essa garantia — é um contrato a nível do desenvolvedor.
De acordo com Swift.org Documentation, 2026, referências unowned são preferíveis a weak em cenários com tempo de vida garantido porque: não requerem um tipo opcional (código mais limpo), não requerem unwrap (menos force-unwrap ou guard let), e não têm sobrecarga de manutenção de uma tabela weak de zeragem. No entanto, qualquer quebra do contrato resulta em um crash.
Em Swift, referências unowned são declaradas com a palavra-chave unowned antes de let ou var. Ao contrário de weak, unowned pode ser tanto let quanto var, e não requer um tipo opcional. Esta propriedade torna unowned conveniente para referências que não podem ser nil por lógica de domínio.
class Country {
let name: String
var capital: City! // será definido após a inicialização
init(name: String) { self.name = name }
}
class City {
let name: String
unowned let country: Country // ✅ unowned let — garantia de vida
init(name: String, country: Country) {
self.name = name
self.country = country
}
}
// Uso
let france = Country(name: "France")
let paris = City(name: "Paris", country: france)
france.capital = paris
// ✅ Country → City (strong), City → Country (unowned) — sem retain cycle
Neste exemplo, City unowned let country — uma cidade não pode existir sem um país. Se o país desaparecer, a cidade (e a referência) perdem seu significado. Semanticamente, este é um caso ideal para unowned: garantia de tempo de vida existe, opcional não é necessário, retain cycle não ocorre.
unowned var é permitido mas menos comum. É usado quando a referência pode ser substituída (por exemplo, religar um filho a um pai diferente). Na reatribuição, a desalocação do objeto antigo é responsabilidade do proprietário externo.
Em Swift 5.0+, foi introduzido suporte para unowned opcional (unowned let x: Type?). Isto é um compromisso: unowned garante que se a referência não for nil, o objeto está vivo. O comportamento ao ser desalocado é um crash, como com unowned regular.
A escolha entre unowned e weak é uma das decisões frequentes ao projetar arquitetura Swift. Vamos examinar os critérios e recomendações para cada caso.
| Critério | Weak | Unowned |
|---|---|---|
| Opcional | Sim (Type?) | Não (Type) |
| Zeragem na desalocação | Auto para nil | Não (risco de ponteiro pendente) |
| Tipo (let/var) | Apenas var | let ou var |
| Desempenho | Sobrecarga de tabela weak | Mínimo (ponteiro simples) |
| Segurança | Seguro (nil verificado) | Risco de EXC_BAD_ACCESS |
| Garantia de tempo de vida | Não requerida | Garantia explícita requerida |
Use weak se houver a menor dúvida sobre o tempo de vida do objeto. Weak é seguro, claro e não requer prova. Use unowned apenas quando puder descartar todos os cenários em que o objeto poderia ser desalocado antes. Casos típicos: um filho que não existe sem um pai; um closure que executa sincronamente; acesso a um objeto dentro de seu inicializador.
De acordo com Airbnb Swift Style Guide, 2025, em bases de código grandes é recomendado usar weak por padrão e unowned apenas com um comentário explícito explicando a garantia de tempo de vida. Isto reduz o risco de crashes não óbvios durante a refatoração.
Closures são o segundo caso de uso mais frequente para unowned após relacionamentos pai-filho. A lista de captura [unowned self] é usada quando é garantido que self sobrevive ao closure. Vamos examinar cenários corretos e incorretos.
Closures síncronos — sorted, filter, map. Eles executam imediatamente na thread atual, self está definitivamente vivo. Uma lista de captura com unowned é aceitável aqui e resulta em código mais limpo.
class DataProcessor {
var items: [Int] = [3, 1, 4, 1, 5]
func processSorted() {
// ✅ unowned self — sorted executa sincronamente, self está garantidamente vivo
let sorted = items.sorted { [unowned self] a, b in
return self.customCompare(a, b)
}
}
func customCompare(_ a: Int, _ b: Int) -> Bool { return a < b }
}
Closures assíncronos — com atrasos, requisições de rede, animações. Self pode ser desalocado entre o agendamento do closure e sua execução. Aqui unowned self leva a um crash. Use [weak self].
class NetworkLoader {
func loadData() {
// ❌ PERIGOSO: unowned self em closure assíncrono
URLSession.shared.dataTask(with: url) { [unowned self] data, _, _ in
self.handleResponse(data) // CRASH se self for liberado
}.resume()
}
func handleResponse(_ data: Data?) { }
// ✅ CORRETO: weak self + guard
func loadDataSafe() {
URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in
guard let self else { return }
self.handleResponse(data)
}.resume()
}
}
Lembre-se da regra: unowned self — apenas para closures síncronos que executam imediatamente. Para closures assíncronos, sempre use weak self + guard let. Exceção: se você explicitamente mantiver uma referência ao objeto até o closure completar (por exemplo, mantendo uma referência forte em outra variável).
Unowned é uma ferramenta poderosa mas perigosa. Vamos examinar cenários do mundo real onde unowned pode levar a crashes e métodos para minimizar o risco.
O principal risco de unowned é uma mudança na lógica de negócio que invalida a garantia de tempo de vida. Um desenvolvedor refatora o código: muda a propriedade, introduz desalocação diferida, adiciona cache — e a referência unowned se torna uma bomba-relógio. O compilador não avisará — apenas um crash no dispositivo do usuário.
Recomendação: use unowned apenas quando a garantia de tempo de vida for óbvia e documentada. Adicione um comentário a cada unowned: por que esta referência é segura e sob quais condições pode ser violada.
UIKit é uma área de alto risco para unowned. Um ViewController pode ser desalocado a qualquer momento durante navegação (pop, dismiss), descarregamento de memória ou mudanças de orientação. Se você passar um ViewController para um closure com unowned self, self pode ser nil ao retornar do background ou ao completar uma animação.
Para reduzir o risco ao usar unowned, siga estas regras:
// Exemplo: referência unowned documentada com justificativa explícita
class InvoiceLineItem {
let productName: String
let price: Decimal
// unowned Invoice — InvoiceLineItem não pode existir sem Invoice.
// Invoice cria Item e remove-o quando é eliminado.
// Garantia: Invoice vive pelo menos tanto quanto Item.
unowned let invoice: Invoice
init(productName: String, price: Decimal, invoice: Invoice) {
self.productName = productName
self.price = price
self.invoice = invoice
}
}
// Esta é uma garantia forte: Invoice remove todos os Items em deinit.
// violar a garantia = um bug na lógica de negócio que precisa ser corrigido.
Documentar garantias é um padrão profissional. Em grandes projetos (Airbnb, Uber), a revisão de código requer justificativa para cada unowned. Se a garantia não for óbvia, use weak. Um comentário em unowned ajuda desenvolvedores futuros a entender por que weak não foi usado aqui e quais condições poderiam quebrar a garantia.
Perguntas Frequentes
Crash em tempo de execução com EXC_BAD_ACCESS. Swift não verifica a validade de uma referência unowned no acesso — é simplesmente um ponteiro “ruim”. Se o objeto é liberado, a memória é sobrescrita e acessá-la termina fatalmente. Esta é uma exceção não capturável (não é try-catch).
Sim, se o protocolo herdar de AnyObject. Unowned funciona com todos os tipos de referência: classes, protocolos AnyObject, objetos Objective-C. Tipos de valor (struct, enum) não suportam unowned porque não participam em ARC.
Quando a garantia de tempo de vida é absoluta e óbvia — unowned é mais seguro de uma perspetiva de design: não requer unwrap, não pode ser nil e não mascara erros. Se um objeto não pode existir sem um pai, unowned torna isso um contrato explícito, enquanto weak difumina a garantia.
Sim: unowned é mais rápido porque não requer acesso à tabela weak em tempo de execução para zeragem. Na maioria das aplicações a diferença é impercetível, mas em cenários de alta carga com milhões de acessos, unowned pode ser 10–20% mais rápido em leituras.
Refatoração é o principal perigo para unowned. Alterar o tempo de vida do objeto (cache, operações assíncronas, reutilização) pode quebrar a garantia. O compilador não avisará. Solução: migre para weak ao mudar a arquitetura ou adicione um comentário de aviso.
Resumo
unowned let ou unowned var; pode ser não opcional e opcional (Swift 5.0+)Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também