Punteros de búfer inseguros
Procese memoria contigua de forma eficiente.
Punteros de búfer inseguros es una lección gratuita de Swift Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Swift Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Swift Academy incluye 4 lecciones en total.
Qué es un puntero de búfer
Un puntero tipado individual apunta a un elemento cada vez. Un UnsafeBufferPointer<T> encapsula un puntero inicial y una cantidad de elementos, lo que proporciona una vista delimitada sobre un bloque contiguo de memoria que cumple con Collection.
Esto significa que puede iterar, acceder mediante subíndices, aplicar map y reduce: todas las API habituales de las colecciones sobre memoria sin procesar.
// A buffer pointer = base address + element count
// UnsafeBufferPointer<Int>(start: ptr, count: 5)Búferes de solo lectura y mutables
Al igual que los punteros individuales, los búferes tienen dos variantes: UnsafeBufferPointer<T> para iterar en modo de solo lectura y UnsafeMutableBufferPointer<T> cuando también necesita asignar elementos.
let p = UnsafeMutablePointer<Int>.allocate(capacity: 4)
p.initialize(repeating: 0, count: 4)
let buf = UnsafeMutableBufferPointer(start: p, count: 4)
buf[0] = 11
print(buf[0]) // 11Iterar como una colección
Como un puntero de búfer es una Collection, un bucle for recorre todos los elementos en orden. No necesita calcular índices manualmente ni preocuparse por errores de límite en el propio bucle, aunque los límites que haya proporcionado siguen siendo su responsabilidad.
let buf = UnsafeMutableBufferPointer<Int>.allocate(capacity: 3)
_ = buf.initialize(from: [10, 20, 30])
for value in buf { print(value) } // 10, 20, 30Algoritmos de colección incluidos
map, filter, reduce, enumerated e indices funcionan con punteros de búfer. Esto le permite procesar memoria sin procesar con código de alto nivel y sin realizar asignaciones.
let buf = UnsafeMutableBufferPointer<Int>.allocate(capacity: 4)
_ = buf.initialize(from: [1, 2, 3, 4])
let total = buf.reduce(0, +) // 10
let evens = buf.filter { $0 % 2 == 0 } // [2, 4]
print(total, evens)Asignar un búfer mutable
UnsafeMutableBufferPointer<T>.allocate(capacity:) reserva el bloque y devuelve un búfer en un solo paso. Aun así, debe llamar a initialize antes de leer y a deallocate cuando haya terminado.
let buf = UnsafeMutableBufferPointer<Int>.allocate(capacity: 5)
buf.initialize(repeating: 0)
defer {
buf.deinitialize()
buf.deallocate()
}Los límites no se comprueban automáticamente
El acceso mediante subíndices dentro de 0..<count es correcto. Sin embargo, el búfer no puede saber si la cantidad que proporcionó era correcta. Si crea un búfer con una cantidad superior a la asignación real, las lecturas sobrepasan el final y acceden a memoria no definida.
Obtenga siempre la cantidad a partir de la misma asignación que haya creado.
let p = UnsafeMutablePointer<Int>.allocate(capacity: 3)
p.initialize(repeating: 0, count: 3)
// CORRECT: count matches capacity
let good = UnsafeBufferPointer(start: p, count: 3)
// WRONG: count: 10 would read past the block
print(good.count)Búferes vacíos
Un búfer con count: 0 es válido y puede tener una dirección base nil. Compruebe siempre isEmpty o confíe en que el bucle simplemente no se ejecute, en lugar de desenvolver forzosamente baseAddress.
let empty = UnsafeBufferPointer<Int>(start: nil, count: 0)
print(empty.isEmpty) // true
print(empty.count) // 0
for _ in empty { print("never runs") }withUnsafeBufferPointer en arrays
La forma más segura de obtener un búfer es partir de un Array existente mediante withUnsafeBufferPointer. Swift garantiza que el almacenamiento sea contiguo y válido durante la ejecución del closure, por lo que evita por completo las asignaciones manuales.
let numbers = [4, 8, 15, 16, 23]
let maxValue = numbers.withUnsafeBufferPointer { buf -> Int in
var m = buf[0]
for v in buf where v > m { m = v }
return m
}
print(maxValue) // 23Modificar el almacenamiento de Array
withUnsafeMutableBufferPointer le permite escribir directamente en el almacenamiento de un array. Esto se utiliza ocasionalmente para transformaciones mutables en el mismo lugar y críticas para el rendimiento, en las que ARC y las comprobaciones de límites añadirían sobrecarga.
var data = [1, 2, 3, 4]
data.withUnsafeMutableBufferPointer { buf in
for i in buf.indices { buf[i] *= 10 }
}
print(data) // [10, 20, 30, 40]baseAddress para API de C
Al llamar a una función de C que espera un puntero y una longitud, pase buffer.baseAddress y buffer.count. La dirección base es nil únicamente en los búferes vacíos, así que debe gestionar ese caso.
let bytes: [UInt8] = [0xDE, 0xAD, 0xBE, 0xEF]
bytes.withUnsafeBufferPointer { buf in
if let base = buf.baseAddress {
// c_function(base, buf.count)
print("start:", base, "len:", buf.count)
}
}Cuándo utilizar punteros de búfer
Utilice punteros de búfer cuando necesite acceder de forma contigua, segura respecto al tipo y siguiendo el estilo de las colecciones a una región de memoria: para conectar arrays de C, analizar formatos binarios o reducir la sobrecarga en bucles críticos. Siempre que sea posible, prefiera las variantes con closure with... a la asignación manual.
// Counting set bits across a byte buffer
let data: [UInt8] = [0b1011, 0b0110, 0b1111]
let bits = data.withUnsafeBufferPointer { buf in
buf.reduce(0) { $0 + $1.nonzeroBitCount }
}
print(bits) // 3 + 2 + 4 = 9Comprobación rápida
Recuerde qué aporta un puntero de búfer frente a un puntero individual.
Resumen
Los punteros de búfer encapsulan una región contigua como una colección delimitada:
UnsafeBufferPointer/UnsafeMutableBufferPointer= dirección base + cantidad.- Puede utilizar
map,filter,reducee iteración conforsobre memoria sin procesar. - Prefiera
withUnsafeBufferPointercon arrays para que Swift gestione la validez y el ciclo de vida. - La cantidad proporcionada se considera correcta: obténgala a partir de la asignación real.
Preguntas frecuentes
¿La lección «Punteros de búfer inseguros» es gratis?
Sí — el texto completo de «Punteros de búfer inseguros» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Swift Academy, actualiza a CoddyKit PRO. El curso de Swift Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Punteros de búfer inseguros»?
Procese memoria contigua de forma eficiente. Practicas Swift Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Swift Academy?
No se requiere experiencia previa. Swift Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Punteros de búfer inseguros»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Swift Academy?
Sí. Cada lección de Swift Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- MemoryLayout y alineación
- UnsafePointer y UnsafeMutablePointer
- Punteros de búfer inseguros
- withUnsafeBytes e interoperabilidad con C