UnsafePointer og UnsafeMutablePointer
Læs og skriv rå hukommelse omhyggeligt.
UnsafePointer og UnsafeMutablePointer er en gratis Swift Academy-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Swift Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Swift Academy-kurset indeholder 4 lektioner i alt.
Typede pointere i Swift
Swifts sikre referencer afslører aldrig rå adresser, men når du arbejder sammen med C eller bygger datastrukturer på lavt niveau, bruger du typede pointere: UnsafePointer<T> til skrivebeskyttet adgang og UnsafeMutablePointer<T> til læsning og skrivning.
En typet pointer kender elementtypen, så den kan beregne afstande og læse en korrekt typet værdi.
// A pointer to an Int we can read but not write
func readFirst(_ p: UnsafePointer<Int>) -> Int {
return p.pointee
}Egenskaben pointee
pointee er den værdi, som pointeren i øjeblikket peger på. Med en modificerbar pointer kan du både læse og tildele den; med en skrivebeskyttet pointer kan du kun læse.
Adgang til pointee i uinitialiseret eller deallokeret hukommelse er udefineret adfærd — typesystemet opdager det ikke.
let p = UnsafeMutablePointer<Int>.allocate(capacity: 1)
p.initialize(to: 42)
print(p.pointee) // 42
p.pointee = 99
print(p.pointee) // 99Allokering af hukommelse
UnsafeMutablePointer<T>.allocate(capacity:) reserverer plads til kapacitets elementer, men initialiserer dem ikke. Hukommelsen er rå, og det er ulovligt at læse den før initialisering.
// Reserve space for 3 Doubles (uninitialized)
let buffer = UnsafeMutablePointer<Double>.allocate(capacity: 3)
// Must initialize before reading any elementinitialize og deinitialize
Før læsning skal du udføre initialize. Før du deallokerer typer, der kræver oprydning, f.eks. klasser eller strenge, skal du udføre deinitialize for at frigive deres ressourcer.
Livscyklussen er: allocate → initialize → use → 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()Sæt altid allocate og deallocate i par
Hver allocate skal modsvares af præcis én deallocate, ellers lækker du hukommelse. Det sikreste mønster er at bruge defer lige efter allokeringen, fordi det kører, uanset hvordan funktionen afsluttes.
func process() {
let p = UnsafeMutablePointer<Int>.allocate(capacity: 1)
defer { p.deallocate() }
p.initialize(to: 7)
print(p.pointee)
} // deallocate runs here automaticallyPointeraritmetik
Typede pointere understøtter indeksering og aritmetik i elementenheder, ikke bytes. p + 2 flytter sig to afstande for T. p[i] er en forkortelse for (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()initialize for flere elementer
For en hukommelsesblok sætter initialize(repeating:count:) hver plads til den samme værdi, mens initialize(from:count:) kopierer fra en anden buffer. Begge initialiserer hele området, så det er sikkert at læse.
let dst = UnsafeMutablePointer<Int>.allocate(capacity: 4)
dst.initialize(repeating: 5, count: 4)
print(dst[3]) // 5
dst.deinitialize(count: 4)
dst.deallocate()Skrivebeskyttet kontra modificerbar
En funktion, der kun undersøger data, bør tage UnsafePointer<T>; en funktion, der ændrer dem, bør tage UnsafeMutablePointer<T>. En modificerbar pointer konverteres implicit til en skrivebeskyttet pointer, men ikke omvendt — det håndhæver hensigten ved API-grænsen.
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 til lokale værdier
Hvis du vil have en midlertidig pointer til en eksisterende værdi uden at allokere, skal du bruge withUnsafePointer(to:) eller den modificerbare form. Pointeren er kun gyldig i closuren — lad den aldrig slippe ud.
var value = 100
withUnsafeMutablePointer(to: &value) { ptr in
ptr.pointee += 1
}
print(value) // 101Almindelige faldgruber
Typede pointere er effektive, men uforsonlige:
- Læsning af
pointeeførinitializeer udefineret. - Hvis du glemmer
deinitializefor typer, der indeholder ressourcer, opstår der lækager. - Hvis en pointer fra
withUnsafePointerslipper ud, får du en hængende pointer.
Her stoler compileren på dig — der er ingen sikkerhedsforanstaltninger under kørsel.
// DANGEROUS — pointer escapes the closure
// var escaped: UnsafePointer<Int>?
// withUnsafePointer(to: &x) { escaped = $0 }
// escaped!.pointee // dangling, undefined behaviorEn lille manuel stak
Hvis vi samler det hele: Allokér en blok, behandl den som elementer ved hjælp af indeksering, og ryd derefter op. Det er grundlaget for brugerdefinerede samlinger og C-integration.
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()Hurtig kontrol
Husk den korrekte pointer-livscyklus.
Opsamling
Du kender nu typede pointere:
UnsafePointerlæser, mensUnsafeMutablePointerlæser og skriver.pointeegiver adgang til værdien; aritmetik foregår i elementenheder.- Livscyklussen er allocate → initialize → use → deinitialize → deallocate, helst beskyttet med
defer.
Derefter ser du, hvordan bufferpointere indkapsler et helt sammenhængende område i en API, der er egnet til Collection.
Lær Swift med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 122
- Lektioner
- 409
Ofte stillede spørgsmål
Er lektionen “UnsafePointer og UnsafeMutablePointer” gratis?
Ja — alle 3 lektioner i læringssporet Swift Academy, inklusive “UnsafePointer og UnsafeMutablePointer”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Swift Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “UnsafePointer og UnsafeMutablePointer”?
Læs og skriv rå hukommelse omhyggeligt. Du øver dig i Swift Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Swift Academy?
Der kræves ingen tidligere erfaring. Swift Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.
Hvor lang tid tager lektionen “UnsafePointer og UnsafeMutablePointer”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Swift Academy-lektion?
Ja. Alle Swift Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- MemoryLayout og alignment
- UnsafePointer og UnsafeMutablePointer
- Unsafe buffer pointers
- withUnsafeBytes og C-interoperabilitet