MemoryLayout og alignment
Undersøg typers størrelse, stride og alignment.
MemoryLayout og alignment er en gratis Swift Academy-lektion på CoddyKit. Dette er lektion 1 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.
Hvorfor hukommelseslayout er vigtigt
Når du arbejder med usikker Swift eller forbinder til C, skal du vide, hvordan værdier arrangeres i hukommelsen. Swift giver dig MemoryLayout<T>, så du kan undersøge dette uden nogensinde at røre ved rå bytes.
Det besvarer tre spørgsmål: Hvor stor er en værdi, hvor langt er der mellem værdier i et array, og på hvilken adressegrænse skal en værdi begynde.
// MemoryLayout works on any type
print(MemoryLayout<Int>.size) // 8 on 64-bit
print(MemoryLayout<Bool>.size) // 1
print(MemoryLayout<Double>.size) // 8size — Faktisk lagerplads
MemoryLayout<T>.size er antallet af bytes, som værdiens betydningsfulde data optager. Det omfatter ikke den afsluttende udfyldning, der kan ligge mellem elementer i et array.
Brug size, når du vil vide, hvor mange betydningsfulde bytes en enkelt værdi indeholder.
struct Point {
var x: Int8 // 1 byte
var y: Int64 // 8 bytes
}
print(MemoryLayout<Point>.size) // 16 (not 9 — padding!)stride — Afstand i arrays
stride er afstanden i bytes mellem begyndelsen af ét element og det næste, når værdier er pakket i et sammenhængende array. Den svarer til size rundet op til alignment.
Når du allokerer buffere manuelt, skal du gange med stride, aldrig med size.
print(MemoryLayout<Point>.stride) // 16
print(MemoryLayout<Int8>.stride) // 1
// Buffer for 10 Points needs:
let bytes = 10 * MemoryLayout<Point>.stride // 160alignment — Adressegrænser
alignment er den bytegrænse, hvorpå en værdi skal begynde. En Int64 med alignment 8 skal begynde på en adresse, der kan divideres med 8. Compileren indsætter udfyldning for at overholde dette.
En structs alignment er den største alignment blandt dens medlemmer.
print(MemoryLayout<Int8>.alignment) // 1
print(MemoryLayout<Int64>.alignment) // 8
print(MemoryLayout<Point>.alignment) // 8Forskellen på size og stride
For mange typer er size == stride, men de er forskellige, når der findes udfyldning. En struct kan have size 9, men stride 16, fordi det næste element skal være 8-byte-alignet.
Tommelfingerregel: Brug size, når du tænker på en enkelt værdi, og stride, når du tænker på samlinger.
struct Mixed {
var flag: Bool // 1
var value: Int // 8
}
print(MemoryLayout<Mixed>.size) // 16
print(MemoryLayout<Mixed>.stride) // 16Feltforskydninger
For structs kan du spørge, hvor hver lagret egenskab befinder sig i forhold til begyndelsen, ved hjælp af MemoryLayout<T>.offset(of:) med en key path. Det er afgørende, når du arrangerer data, så de passer til en C-struct.
struct Header {
var magic: UInt32 // offset 0
var length: UInt64 // offset 8 (padded)
}
print(MemoryLayout<Header>.offset(of: \Header.magic) ?? -1) // 0
print(MemoryLayout<Header>.offset(of: \Header.length) ?? -1) // 8Omarrangering for at spare plads
På grund af alignment påvirker rækkefølgen af lagrede egenskaber størrelsen. Hvis du placerer større felter først eller grupperer efter størrelse, kan du gøre en struct mindre. Det er vigtigt for store arrays, hvor spildte bytes løber op.
struct Wasteful { var a: Int8; var b: Int64; var c: Int8 } // size 24
struct Tight { var b: Int64; var a: Int8; var c: Int8 } // size 16
print(MemoryLayout<Wasteful>.size)
print(MemoryLayout<Tight>.size)Layout for referencer
En klasseinstans allokeres på heapen, så en variabel, der indeholder en klassereference, blot er en pointer. Dens MemoryLayout.size er pointerens størrelse, 8 bytes, uanset hvor stort objektet er.
Værdityper som structs gemmer deres indhold direkte; referencetyper gemmer kun pointeren.
class Big { var data = [Int](repeating: 0, count: 1000) }
print(MemoryLayout<Big>.size) // 8 — just the referenceValgfrie typer og enumerationer
Valgfrie typer føjer normalt en byte til som mærke, men Swift optimerer valgfrie referencer ved at genbruge null-pointeren, så String? kan have samme størrelse som String.
Enumerationer med tilknyttede værdier dimensioneres, så de kan rumme deres største tilfælde plus en skelneværdi.
print(MemoryLayout<Int?>.size) // 9
print(MemoryLayout<String>.size) // 16
print(MemoryLayout<String?>.size) // 16 — no extra byteBrug af of: med en instans
Hvert medlem (size, stride, alignment) har også en instansbaseret form: MemoryLayout.size(ofValue:). Det er praktisk, når typen er svær at skrive ud eller bliver udledt.
let tuple = (UInt8(1), UInt64(2))
print(MemoryLayout.size(ofValue: tuple)) // 16
print(MemoryLayout.stride(ofValue: tuple)) // 16
print(MemoryLayout.alignment(ofValue: tuple)) // 8Allokering med korrekt layout
Når du allokerer rå hukommelse, skal du angive både byteantal og alignment. Hvis du henter disse fra MemoryLayout, er du sikker på, at det er korrekt på tværs af arkitekturer, i stedet for at hardkode tal.
let count = 4
let capacity = count * MemoryLayout<Int>.stride
let align = MemoryLayout<Int>.alignment
let raw = UnsafeMutableRawPointer.allocate(
byteCount: capacity, alignment: align)
defer { raw.deallocate() }Hurtig kontrol
Afprøv din forståelse af forskellen på size og stride.
Opsamling
Du har lært hukommelseslayoutets tre grundpiller:
- size — betydningsfulde bytes i en enkelt værdi
- stride — afstanden mellem array-elementer (brug denne ved allokering)
- alignment — den nødvendige begyndelsesgrænse
Du har også set offset(of:) til feltplaceringer, hvordan egenskabernes rækkefølge påvirker størrelsen, og at referencer blot har pointerstørrelse. Disse værktøjer lader dig allokere og fortolke rå hukommelse sikkert.
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 “MemoryLayout og alignment” gratis?
Ja — alle 3 lektioner i læringssporet Swift Academy, inklusive “MemoryLayout og alignment”, 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 “MemoryLayout og alignment”?
Undersøg typers størrelse, stride og alignment. 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 1 af 4.
Hvor lang tid tager lektionen “MemoryLayout og alignment”?
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