UnsafePointer e UnsafeMutablePointer
Leia e escreva na memória bruta com cuidado.
UnsafePointer e UnsafeMutablePointer é uma aula grátis de Swift Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Swift Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Swift Academy inclui 4 aulas no total.
Ponteiros tipados em Swift
As referências seguras do Swift nunca expõem endereços brutos, mas, ao fazer a interoperabilidade com C ou criar estruturas de dados de baixo nível, você recorre a ponteiros tipados: UnsafePointer<T> para acesso somente leitura e UnsafeMutablePointer<T> para leitura e gravação.
Um ponteiro tipado conhece o tipo do elemento, portanto pode calcular strides e ler um valor com o tipo correto.
// A pointer to an Int we can read but not write
func readFirst(_ p: UnsafePointer<Int>) -> Int {
return p.pointee
}A propriedade referenciada
pointee é o valor ao qual o ponteiro aponta atualmente. Em um ponteiro mutável, você pode tanto lê-lo quanto atribuir um valor a ele; em um ponteiro somente leitura, pode apenas lê-lo.
Acessar pointee em memória não inicializada ou desalocada é comportamento indefinido — o sistema de tipos não detectará isso.
let p = UnsafeMutablePointer<Int>.allocate(capacity: 1)
p.initialize(to: 42)
print(p.pointee) // 42
p.pointee = 99
print(p.pointee) // 99Alocando memória
UnsafeMutablePointer<T>.allocate(capacity:) reserva espaço para capacity elementos, mas não os inicializa. A memória é raw, e lê-la antes da inicialização é ilegal.
// Reserve space for 3 Doubles (uninitialized)
let buffer = UnsafeMutablePointer<Double>.allocate(capacity: 3)
// Must initialize before reading any elementinitialize e deinitialize
Antes de ler, você deve usar initialize. Antes de desalocar tipos que exigem limpeza, como classes ou strings, você deve usar deinitialize para liberar seus recursos.
O ciclo de vida é: allocate → initialize → usar → deinitialize → deallocate.
let p = UnsafeMutablePointer<String>.allocate(capacity: 1)
p.initialize(to: "hello")
print(p.pointee)
p.deinitialize(count: 1) // releases the String
p.deallocate()Sempre associe allocate a deallocate
Cada allocate deve corresponder a exatamente um deallocate, caso contrário haverá um vazamento de memória. Usar defer logo após a alocação é o padrão mais seguro, pois ele é executado independentemente de como a função termina.
func process() {
let p = UnsafeMutablePointer<Int>.allocate(capacity: 1)
defer { p.deallocate() }
p.initialize(to: 7)
print(p.pointee)
} // deallocate runs here automaticallyAritmética de ponteiros
Os ponteiros tipados aceitam indexação e aritmética em unidades de elementos, não em bytes. p + 2 avança duas strides de T. p[i] é uma forma abreviada de (p + i).pointee.
let p = UnsafeMutablePointer<Int>.allocate(capacity: 3)
p.initialize(repeating: 0, count: 3)
p[0] = 10
p[1] = 20
p[2] = 30
print((p + 1).pointee) // 20
p.deinitialize(count: 3)
p.deallocate()Inicializando vários elementos
Para um bloco de memória, initialize(repeating:count:) define cada posição com o mesmo valor, enquanto initialize(from:count:) copia de outro buffer. Ambos inicializam completamente o intervalo, tornando seguro fazer a leitura.
let dst = UnsafeMutablePointer<Int>.allocate(capacity: 4)
dst.initialize(repeating: 5, count: 4)
print(dst[3]) // 5
dst.deinitialize(count: 4)
dst.deallocate()Somente leitura versus mutável
Uma função que apenas inspeciona dados deve receber UnsafePointer<T>; uma que os modifica deve receber UnsafeMutablePointer<T>. Um ponteiro mutável é convertido implicitamente em um ponteiro somente leitura, mas o inverso não é possível — isso reforça a intenção no limite da API.
func sum(_ p: UnsafePointer<Int>, _ n: Int) -> Int {
var total = 0
for i in 0..<n { total += p[i] }
return total
}
// A mutable pointer can be passed here directlywithUnsafePointer para variáveis locais
Para obter um ponteiro temporário para um valor existente sem alocar memória, use withUnsafePointer(to:) ou sua forma mutável. O ponteiro só é válido dentro do bloco — nunca permita que ele escape.
var value = 100
withUnsafeMutablePointer(to: &value) { ptr in
ptr.pointee += 1
}
print(value) // 101Armadilhas comuns
Ponteiros tipados são poderosos, mas não perdoam erros:
- Ler
pointeeantes deinitializeresulta em comportamento indefinido. - Esquecer
deinitializeem tipos que mantêm recursos causa vazamentos. - Permitir que um ponteiro de
withUnsafePointerescape cria um ponteiro pendente.
O compilador confia em você aqui — não há proteções em tempo de execução.
// DANGEROUS — pointer escapes the closure
// var escaped: UnsafePointer<Int>?
// withUnsafePointer(to: &x) { escaped = $0 }
// escaped!.pointee // dangling, undefined behaviorUma pequena stack manual
Reunindo tudo: aloque um bloco, trate-o como elementos usando indexação e depois faça a limpeza. Essa é a base de coleções personalizadas e da interoperabilidade com C.
let n = 3
let stack = UnsafeMutablePointer<Int>.allocate(capacity: n)
stack.initialize(repeating: 0, count: n)
for i in 0..<n { stack[i] = i * i }
// stack now holds 0, 1, 4
stack.deinitialize(count: n)
stack.deallocate()Verificação rápida
Relembre o ciclo de vida correto dos ponteiros.
Recapitulação
Agora você conhece os ponteiros tipados:
UnsafePointerlê;UnsafeMutablePointerlê e grava.pointeeacessa o valor; a aritmética é feita em unidades de elementos.- O ciclo de vida é allocate → initialize → usar → deinitialize → deallocate, idealmente protegido com
defer.
A seguir, você verá como ponteiros de buffer envolvem uma região contígua inteira em uma API compatível com coleções.
Perguntas Frequentes
A aula “UnsafePointer e UnsafeMutablePointer” é grátis?
Sim — o texto completo de “UnsafePointer e UnsafeMutablePointer” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Swift Academy, atualize para CoddyKit PRO. O curso de Swift Academy inclui 4 aulas no total.
O que vou aprender em “UnsafePointer e UnsafeMutablePointer”?
Leia e escreva na memória bruta com cuidado. Você pratica Swift Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Swift Academy?
Nenhuma experiência prévia é necessária. Swift Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “UnsafePointer e UnsafeMutablePointer”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Swift Academy?
Sim. Cada aula de Swift Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- MemoryLayout e Alinhamento
- UnsafePointer e UnsafeMutablePointer
- Ponteiros de Buffer Inseguros
- withUnsafeBytes e Interoperabilidade com C