Pointeurs de tampons non sûrs
Traitez efficacement la mémoire contiguë.
Pointeurs de tampons non sûrs est une leçon Swift Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Swift Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Swift Academy comprend 4 leçons au total.
Qu'est-ce qu'un pointeur de tampon
Un pointeur unique de type typed adresse un seul élément à la fois. Un UnsafeBufferPointer<T> encapsule un pointeur de début et un nombre d'éléments, ce qui vous fournit une vue bornée sur un bloc contigu de mémoire qui respecte le protocole Collection.
Vous pouvez ainsi parcourir, indexer, transformer avec map et réduire avec reduce — toutes les API familières des collections appliquées à la mémoire raw.
// A buffer pointer = base address + element count
// UnsafeBufferPointer<Int>(start: ptr, count: 5)Buffers en lecture seule ou modifiables
Comme les pointeurs simples, les buffers existent sous deux formes : UnsafeBufferPointer<T> pour le parcours en lecture seule, et UnsafeMutableBufferPointer<T> lorsque vous devez également affecter des éléments.
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]) // 11Parcourir comme une collection
Comme un buffer est une Collection, une boucle for parcourt chaque élément dans l'ordre. Aucun calcul d'indice manuel, aucun risque de décalage d'une unité dans la boucle elle-même — même si les limites que vous avez fournies restent sous votre responsabilité.
let buf = UnsafeMutableBufferPointer<Int>.allocate(capacity: 3)
_ = buf.initialize(from: [10, 20, 30])
for value in buf { print(value) } // 10, 20, 30Des algorithmes de collection sans effort
map, filter, reduce, enumerated et indices fonctionnent tous avec les pointeurs de tampon. Vous pouvez ainsi traiter la mémoire raw avec du code de haut niveau, tout en évitant les allocations.
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)Allouer un tampon modifiable
UnsafeMutableBufferPointer<T>.allocate(capacity:) réserve le bloc et renvoie un tampon en une seule étape. Vous devez tout de même initialize avant toute lecture et appeler deallocate lorsque vous avez terminé.
let buf = UnsafeMutableBufferPointer<Int>.allocate(capacity: 5)
buf.initialize(repeating: 0)
defer {
buf.deinitialize()
buf.deallocate()
}Les limites ne sont pas vérifiées à l'extrémité
L'indexation dans 0..<count est correcte. Mais le buffer ne peut pas savoir si le count que vous avez fourni était correct. Si vous créez un buffer avec un count supérieur à l'allocation réelle, les lectures dépassent sa fin et accèdent à une mémoire indéfinie.
Dérivez toujours le count de la même allocation que celle que vous avez créée.
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)Buffers empty
Un buffer avec count: 0 est valide et peut avoir une adresse de base nil. Vérifiez toujours isEmpty, ou faites simplement confiance au fait que la boucle ne s'exécutera pas, plutôt que de forcer le déballage de baseAddress.
let empty = UnsafeBufferPointer<Int>(start: nil, count: 0)
print(empty.isEmpty) // true
print(empty.count) // 0
for _ in empty { print("never runs") }withUnsafeBufferPointer sur les tableaux
La manière la plus sûre d'obtenir un buffer consiste à partir d'un Array existant via withUnsafeBufferPointer. Swift garantit que le stockage est contigu et valide pendant toute la durée de la fermeture, ce qui vous évite toute allocation manuelle.
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) // 23Modifier le stockage d'un tableau
withUnsafeMutableBufferPointer vous permet d'écrire directement dans le stockage d'un tableau. Cette technique est parfois utilisée pour les transformations sur place critiques en matière de performances, lorsque ARC et les vérifications de limites ajouteraient une surcharge.
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 pour les API C
Lorsqu'une fonction C attend un pointeur accompagné d'une longueur, transmettez buffer.baseAddress et buffer.count. L'adresse de base vaut nil uniquement pour les buffers vides ; gérez donc ce cas.
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)
}
}Quand utiliser les pointeurs de tampon
Utilisez les pointeurs de tampon lorsque vous avez besoin d'un accès contigu, sûr du point de vue des types et semblable à celui d'une collection sur une région de mémoire : pour relier des tableaux C, analyser des formats binaires ou réduire la surcharge dans les boucles intensives. Privilégiez autant que possible les formes avec fermeture with... plutôt que l'allocation manuelle.
// 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 = 9Vérification rapide
Rappelez-vous ce qu'ajoute un pointeur de tampon par rapport à un pointeur simple.
Récapitulatif
Les pointeurs de tampon encapsulent une région contiguë sous la forme d'une collection bornée :
UnsafeBufferPointer/UnsafeMutableBufferPointer= adresse de base + nombre d'éléments.- Vous bénéficiez de
map,filter,reduceet du parcours avecforsur la mémoire raw. - Privilégiez
withUnsafeBufferPointersur les tableaux afin que Swift gère la validité et la durée de vie. - Le count fourni est considéré comme fiable — dérivez-le de l'allocation réelle.
Questions Fréquemment Posées
La leçon « Pointeurs de tampons non sûrs » est-elle gratuite ?
Oui — le texte complet de « Pointeurs de tampons non sûrs » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Swift Academy, passe à CoddyKit PRO. Le cours Swift Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Pointeurs de tampons non sûrs » ?
Traitez efficacement la mémoire contiguë. Tu pratiques Swift Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Swift Academy ?
Aucune expérience préalable n'est requise. Swift Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Pointeurs de tampons non sûrs » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Swift Academy ?
Oui. Chaque leçon Swift Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- MemoryLayout et alignement
- UnsafePointer et UnsafeMutablePointer
- Pointeurs de tampons non sûrs
- withUnsafeBytes et interopérabilité C