UnsafePointer dan UnsafeMutablePointer
Baca dan tulis memori mentah dengan hati-hati.
UnsafePointer dan UnsafeMutablePointer adalah pelajaran Swift Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Swift Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Swift Academy mencakup 4 pelajaran total.
Penunjuk Bertipe di Swift
Referensi aman Swift tidak pernah mengekspos alamat raw, tetapi saat berinteroperasi dengan C atau membangun struktur data tingkat rendah, Anda dapat menggunakan penunjuk bertipe: UnsafePointer<T> untuk akses hanya-baca dan UnsafeMutablePointer<T> untuk baca/tulis.
Penunjuk bertipe mengetahui jenis elemennya, sehingga dapat menghitung stride dan membaca nilai dengan jenis yang tepat.
// A pointer to an Int we can read but not write
func readFirst(_ p: UnsafePointer<Int>) -> Int {
return p.pointee
}Properti Nilai yang Ditunjuk
pointee adalah nilai yang sedang ditunjuk oleh penunjuk. Pada penunjuk yang dapat diubah, Anda dapat membaca dan menetapkan nilainya; pada penunjuk hanya-baca, Anda hanya dapat membacanya.
Mengakses pointee pada memori yang belum diinisialisasi atau telah di-deallocate merupakan perilaku tak terdefinisi — sistem jenis tidak akan mendeteksinya.
let p = UnsafeMutablePointer<Int>.allocate(capacity: 1)
p.initialize(to: 42)
print(p.pointee) // 42
p.pointee = 99
print(p.pointee) // 99Mengalokasikan Memori
UnsafeMutablePointer<T>.allocate(capacity:) menyediakan ruang untuk elemen sebanyak capacity, tetapi tidak menginisialisasinya. Memori tersebut bersifat raw dan membacanya sebelum inisialisasi merupakan tindakan ilegal.
// Reserve space for 3 Doubles (uninitialized)
let buffer = UnsafeMutablePointer<Double>.allocate(capacity: 3)
// Must initialize before reading any elementMenginisialisasi dan Menghapus Inisialisasi
Sebelum membaca, Anda harus menjalankan initialize. Sebelum men-deallocate jenis yang memerlukan pembersihan (seperti kelas atau string), Anda harus menjalankan deinitialize untuk melepaskan sumber dayanya.
Siklus hidupnya adalah: allocate → initialize → gunakan → 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()Selalu Pasangkan allocate dengan deallocate
Setiap allocate harus dipasangkan tepat dengan satu deallocate, atau akan terjadi kebocoran memori. Menggunakan defer segera setelah alokasi adalah pola yang paling aman karena selalu dijalankan, apa pun cara fungsi berakhir.
func process() {
let p = UnsafeMutablePointer<Int>.allocate(capacity: 1)
defer { p.deallocate() }
p.initialize(to: 7)
print(p.pointee)
} // deallocate runs here automaticallyAritmetika Penunjuk
Penunjuk bertipe mendukung pengindeksan dan aritmetika dalam satuan elemen, bukan bytes. p + 2 maju sebanyak dua stride dari T. p[i] adalah bentuk singkat dari (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()Menginisialisasi Beberapa Elemen
Untuk blok memori, initialize(repeating:count:) menetapkan nilai yang sama ke setiap slot, sedangkan initialize(from:count:) menyalin dari buffer lain. Keduanya menginisialisasi seluruh rentang, sehingga aman untuk dibaca.
let dst = UnsafeMutablePointer<Int>.allocate(capacity: 4)
dst.initialize(repeating: 5, count: 4)
print(dst[3]) // 5
dst.deinitialize(count: 4)
dst.deallocate()Hanya-Baca dan Dapat Diubah
Fungsi yang hanya memeriksa data sebaiknya menerima UnsafePointer<T>; fungsi yang mengubahnya menerima UnsafeMutablePointer<T>. Penunjuk yang dapat diubah secara implisit dapat dikonversi menjadi penunjuk hanya-baca, tetapi tidak sebaliknya — hal ini menegakkan maksud pada batas API.
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 untuk Variabel Lokal
Untuk mendapatkan penunjuk sementara ke nilai yang sudah ada tanpa mengalokasikan memori, gunakan withUnsafePointer(to:) atau bentuk yang dapat diubah. Penunjuk tersebut hanya valid di dalam penutupan — jangan pernah membiarkannya keluar.
var value = 100
withUnsafeMutablePointer(to: &value) { ptr in
ptr.pointee += 1
}
print(value) // 101Kesalahan Umum
Penunjuk bertipe memang kuat, tetapi tidak memberi banyak toleransi terhadap kesalahan:
- Membaca
pointeesebeluminitializemenghasilkan perilaku tak terdefinisi. - Lupa menjalankan
deinitializepada jenis yang menyimpan sumber daya menyebabkan kebocoran. - Membiarkan penunjuk dari
withUnsafePointerkeluar menghasilkan penunjuk yang menggantung.
Kompilator mempercayai Anda dalam hal ini — tidak ada perlindungan saat runtime.
// DANGEROUS — pointer escapes the closure
// var escaped: UnsafePointer<Int>?
// withUnsafePointer(to: &x) { escaped = $0 }
// escaped!.pointee // dangling, undefined behaviorTumpukan Manual Sederhana
Jika digabungkan: alokasikan sebuah blok, perlakukan sebagai elemen dengan pengindeksan, lalu bersihkan. Inilah dasar koleksi khusus dan interoperabilitas C.
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()Pemeriksaan Singkat
Ingat kembali siklus hidup penunjuk yang benar.
Ringkasan
Sekarang Anda telah memahami penunjuk bertipe:
UnsafePointermembaca, sedangkanUnsafeMutablePointermembaca dan menulis.pointeemengakses nilai; aritmetika dilakukan dalam satuan elemen.- Siklus hidupnya adalah allocate → initialize → gunakan → deinitialize → deallocate, idealnya dilindungi dengan
defer.
Selanjutnya, Anda akan melihat cara penunjuk buffer membungkus seluruh wilayah berkesinambungan dalam API yang ramah terhadap Collection.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “UnsafePointer dan UnsafeMutablePointer” gratis?
Ya — teks lengkap “UnsafePointer dan UnsafeMutablePointer” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Swift Academy, upgrade ke CoddyKit PRO. Kursus Swift Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “UnsafePointer dan UnsafeMutablePointer”?
Baca dan tulis memori mentah dengan hati-hati. Kamu berlatih Swift Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Swift Academy?
Tidak diperlukan pengalaman sebelumnya. Swift Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “UnsafePointer dan UnsafeMutablePointer” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Swift Academy ini?
Ya. Setiap pelajaran Swift Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- MemoryLayout dan Alignment
- UnsafePointer dan UnsafeMutablePointer
- Pointer Buffer Tidak Aman
- withUnsafeBytes dan Interoperabilitas C