MemoryLayout dan Penjajaran
Periksa saiz, stride dan penjajaran jenis.
MemoryLayout dan Penjajaran ialah pelajaran Swift Academy percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Swift Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Swift Academy merangkumi sejumlah 4 pelajaran.
Mengapa Susun Atur Memori Penting
Apabila anda bekerja dengan Swift yang tidak selamat atau menjambatani C, anda perlu mengetahui cara nilai disusun dalam memori. Swift menyediakan MemoryLayout<T> untuk memeriksa perkara ini tanpa menyentuh bait raw.
Ia menjawab tiga soalan: berapa besar sesuatu nilai, sejauh mana jarak antara nilai dalam tatasusunan, dan pada sempadan alamat manakah sesuatu nilai mesti bermula.
// MemoryLayout works on any type
print(MemoryLayout<Int>.size) // 8 on 64-bit
print(MemoryLayout<Bool>.size) // 1
print(MemoryLayout<Double>.size) // 8size — Storan Sebenar
MemoryLayout<T>.size ialah bilangan bytes yang digunakan oleh data penting sesuatu nilai. Ia tidak termasuk pad tambahan di hujung yang mungkin berada antara elemen dalam tatasusunan.
Gunakan size apabila anda ingin mengetahui jumlah bytes bermakna yang disimpan oleh satu nilai.
struct Point {
var x: Int8 // 1 byte
var y: Int64 // 8 bytes
}
print(MemoryLayout<Point>.size) // 16 (not 9 — padding!)stride — Jarak dalam Tatasusunan
stride ialah jarak dalam bytes antara permulaan satu elemen dengan elemen seterusnya apabila nilai disusun dalam tatasusunan bersebelahan. Nilainya sama dengan size yang dibundarkan ke atas mengikut alignment.
Apabila anda memperuntukkan penimbal secara manual, darabkan dengan stride, dan jangan sekali-kali dengan size.
print(MemoryLayout<Point>.stride) // 16
print(MemoryLayout<Int8>.stride) // 1
// Buffer for 10 Points needs:
let bytes = 10 * MemoryLayout<Point>.stride // 160alignment — Sempadan Alamat
alignment ialah sempadan bait tempat sesuatu nilai mesti bermula. Nilai integer 64-bit dengan alignment 8 mesti bermula pada alamat yang boleh dibahagi dengan 8. Pengkompil memasukkan pad untuk mematuhi syarat ini.
Alignment sesuatu struktur ialah alignment terbesar antara ahlinya.
print(MemoryLayout<Int8>.alignment) // 1
print(MemoryLayout<Int64>.alignment) // 8
print(MemoryLayout<Point>.alignment) // 8Perbezaan size dengan stride
Bagi banyak jenis, size == stride, tetapi kedua-duanya berbeza apabila terdapat pad. Sesuatu struktur mungkin mempunyai size 9 tetapi stride 16 kerana elemen seterusnya mesti sejajar pada sempadan 8 bait.
Panduan umum: gunakan size untuk memahami satu nilai dan stride untuk memahami koleksi.
struct Mixed {
var flag: Bool // 1
var value: Int // 8
}
print(MemoryLayout<Mixed>.size) // 16
print(MemoryLayout<Mixed>.stride) // 16Offset Medan
Bagi struktur, anda boleh mengetahui kedudukan setiap sifat tersimpan berbanding permulaan menggunakan MemoryLayout<T>.offset(of:) dengan laluan kunci. Ini penting apabila menyusun data agar sepadan dengan struktur C.
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) // 8Menyusun Semula untuk Menjimatkan Ruang
Disebabkan alignment, susunan sifat tersimpan mempengaruhi size. Meletakkan medan yang lebih besar dahulu atau mengumpulkannya mengikut size boleh mengecilkan struktur. Perkara ini penting bagi tatasusunan besar kerana bytes yang dibazirkan akan terkumpul.
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)Susun Atur Rujukan
Sesuatu tika kelas diperuntukkan pada timbunan, jadi pemboleh ubah yang menyimpan rujukan kelas hanyalah sebuah penuding. MemoryLayout.sizenya ialah saiz penuding, iaitu 8 bytes, tanpa mengira saiz objek tersebut.
Jenis nilai seperti struktur menyimpan kandungannya secara sebaris; jenis rujukan hanya menyimpan penuding.
class Big { var data = [Int](repeating: 0, count: 1000) }
print(MemoryLayout<Big>.size) // 8 — just the referenceNilai Pilihan dan Enumerasi
Nilai pilihan biasanya menambah satu bait untuk penanda, tetapi Swift mengoptimumkan nilai pilihan rujukan dengan menggunakan semula penuding null, jadi String? boleh mempunyai size yang sama seperti String.
Enumerasi dengan nilai berkaitan disukat untuk menyimpan kes terbesarnya bersama diskriminator.
print(MemoryLayout<Int?>.size) // 9
print(MemoryLayout<String>.size) // 16
print(MemoryLayout<String?>.size) // 16 — no extra byteMenggunakan Bentuk Berasaskan Contoh
Setiap ahli (size, stride, alignment) juga mempunyai bentuk berasaskan contoh: MemoryLayout.size(ofValue:). Ini berguna apabila jenis sukar dinyatakan sepenuhnya atau dibuat kesimpulan secara automatik.
let tuple = (UInt8(1), UInt64(2))
print(MemoryLayout.size(ofValue: tuple)) // 16
print(MemoryLayout.stride(ofValue: tuple)) // 16
print(MemoryLayout.alignment(ofValue: tuple)) // 8Memperuntukkan dengan Susun Atur yang Betul
Apabila anda memperuntukkan memori raw, anda mesti memberikan kedua-dua bilangan bytes dan alignment. Mendapatkan nilai ini daripada MemoryLayout menjamin ketepatan merentas seni bina, berbanding menetapkan nombor secara manual.
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() }Semak Pantas
Uji pemahaman anda tentang size berbanding stride.
Imbas Kembali
Anda telah mempelajari tiga asas susun atur memori:
- size — bytes bermakna bagi satu nilai
- stride — jarak antara elemen tatasusunan (gunakan ini untuk peruntukan)
- alignment — sempadan permulaan yang diperlukan
Anda juga telah melihat offset(of:) untuk kedudukan medan, cara susunan sifat mempengaruhi size, dan bahawa rujukan hanya bersaiz penuding. Alat ini membolehkan anda memperuntukkan dan mentafsir memori raw dengan selamat.
Pelajari Swift dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 122
- Pelajaran
- 409
Soalan Lazim
Adakah pelajaran “MemoryLayout dan Penjajaran” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Swift Academy, termasuk “MemoryLayout dan Penjajaran”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Swift Academy merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “MemoryLayout dan Penjajaran”?
Periksa saiz, stride dan penjajaran jenis. Anda berlatih Swift Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Swift Academy?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Swift Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.
Berapa lamakah pelajaran “MemoryLayout dan Penjajaran” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Swift Academy ini?
Ya. Setiap pelajaran Swift Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- MemoryLayout dan Penjajaran
- UnsafePointer dan UnsafeMutablePointer
- Penuding Penimbal Tidak Selamat
- withUnsafeBytes dan Interop C