Unowned Reference: o que é, sintaxe e uso em aplicações móveis

Autor: IT Sectr Publicado: 2026-03-30 Tempo de leitura: 9 min

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 — referência não proprietária sem zeragem automática; não opcional, não aumenta o retain count
  • Garantia — usado quando o objeto está garantido a não ser liberado antes do objeto que o referencia
  • Diferença de weak — unowned não zera para nil (risco de crash), weak zera (seguro)
  • Cenários — pai-filho com garantia de vida, closures com unowned self, singletons e Service Locator
  • Risco — acessar um objeto unowned liberado causa um crash em tempo de execução (EXC_BAD_ACCESS)

O que é Unowned Reference?

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.

Sintaxe de unowned em Swift

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.

swift
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

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.

Unowned Optional

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.

Unowned vs Weak: quando usar o quê

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érioWeakUnowned
OpcionalSim (Type?)Não (Type)
Zeragem na desalocaçãoAuto para nilNão (risco de ponteiro pendente)
Tipo (let/var)Apenas varlet ou var
DesempenhoSobrecarga de tabela weakMínimo (ponteiro simples)
SegurançaSeguro (nil verificado)Risco de EXC_BAD_ACCESS
Garantia de tempo de vidaNão requeridaGarantia explícita requerida

Regra Prática

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.

Unowned self em Closures

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.

Quando unowned self é seguro

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.

swift
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 }
}

Quando unowned self é perigoso

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].

swift
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).

Riscos de unowned e como evitá-los

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.

Refatoração e Mudança de Garantias

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.

Unowned em Hierarquias UIKit

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.

Melhores Práticas

Para reduzir o risco ao usar unowned, siga estas regras:

  • Prefira weak por padrão — weak é seguro, unowned é uma otimização, não um padrão
  • Documente as garantias — para cada unowned, escreva um comentário com justificativa
  • Evite unowned em ViewController — o ciclo de vida do UIKit é imprevisível para garantias unowned
  • Use unowned apenas para closures síncronos — sorted, filter, map são candidatos seguros
  • Verifique durante revisão de código — cada unowned requer justificativa do autor do código
  • Migre para weak à menor dúvida — a perda em legibilidade (um guard let) é menor que um crash em produção
swift
// 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

O que acontece ao acessar uma referência unowned após o objeto ser liberado?

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).

Pode-se usar unowned com protocolos?

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 unowned é mais seguro que weak?

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.

Há diferença de desempenho entre unowned e weak?

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.

Como a refatoração afeta as garantias de unowned?

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 Reference — referência não proprietária sem zeragem; não opcional, não aumenta retain count
  • Garantia — requer prova explícita de que o objeto vive pelo menos tanto quanto o código que o referencia
  • Sintaxeunowned let ou unowned var; pode ser não opcional e opcional (Swift 5.0+)
  • Unowned vs Weak — unowned é mais rápido e limpo, mas weak é mais seguro; weak é a escolha padrão
  • Closures — unowned self apenas para closures síncronos; assíncronos requerem [weak self]
  • Documentação — cada unowned deve ter um comentário justificando a garantia
  • Recomendação — na dúvida, escolha weak; unowned é para contratos explícitos e documentados

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.

Discutir o projeto

Leia também