UnsafePointer ve UnsafeMutablePointer
Ham belleği dikkatle okuyun ve yazın.
UnsafePointer ve UnsafeMutablePointer, CoddyKit'te ücretsiz bir Swift Academy dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Swift Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Swift Academy kursu toplamda 4 dersten oluşur.
Swift'te türlendirilmiş işaretçiler
Swift'in güvenli başvuruları ham adresleri açığa çıkarmaz, ancak C ile birlikte çalışırken veya düşük düzeyli veri yapıları oluştururken türlendirilmiş işaretçilere başvurursunuz: salt okunur erişim için UnsafePointer<T>, okuma ve yazma için UnsafeMutablePointer<T>.
Türlendirilmiş bir işaretçi öğe türünü bilir; böylece stride değerlerini hesaplayabilir ve uygun türdeki bir değeri okuyabilir.
// A pointer to an Int we can read but not write
func readFirst(_ p: UnsafePointer<Int>) -> Int {
return p.pointee
}İşaret edilen değer özelliği
pointee, işaretçinin o anda adreslediği değerdir. Değiştirilebilir bir işaretçide bu değeri hem okuyabilir hem de atayabilirsiniz; salt okunur bir işaretçide ise yalnızca okuyabilirsiniz.
Başlatılmamış veya serbest bırakılmış bellekte pointee'ye erişmek tanımsız davranıştır — tür sistemi bunu yakalayamaz.
let p = UnsafeMutablePointer<Int>.allocate(capacity: 1)
p.initialize(to: 42)
print(p.pointee) // 42
p.pointee = 99
print(p.pointee) // 99Bellek ayırma
UnsafeMutablePointer<T>.allocate(capacity:), capacity sayıda öğe için yer ayırır ancak bu öğeleri başlatmaz. Bellek hamdır ve başlatmadan önce okumak yasa dışıdır.
// Reserve space for 3 Doubles (uninitialized)
let buffer = UnsafeMutablePointer<Double>.allocate(capacity: 3)
// Must initialize before reading any elementInitialize ve Deinitialize
Okumadan önce initialize kullanarak başlatmanız gerekir. Sınıflar veya dizeler gibi temizlenmesi gereken türlerin belleğini serbest bırakmadan önce kaynaklarını serbest bırakmak için deinitialize kullanmanız gerekir.
Yaşam döngüsü şöyledir: 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()allocate ile deallocate işlemlerini her zaman eşleştirin
Her allocate işlemi tam olarak bir deallocate işlemiyle eşleştirilmelidir; aksi hâlde bellek sızıntısı oluşur. Ayırma işleminden hemen sonra defer kullanmak en güvenli düzendir, çünkü işlev nasıl sonlanırsa sonlansın çalışır.
func process() {
let p = UnsafeMutablePointer<Int>.allocate(capacity: 1)
defer { p.deallocate() }
p.initialize(to: 7)
print(p.pointee)
} // deallocate runs here automaticallyİşaretçi aritmetiği
Türlendirilmiş işaretçiler dizinlemeyi ve aritmetiği baytlarla değil, öğe birimleriyle destekler. p + 2, T türünün iki stride değeri kadar ilerler. p[i], (p + i).pointee ifadesinin kısa biçimidir.
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()Birden çok öğeyi başlatma
Bir bellek bloğu için initialize(repeating:count:) her yuvayı aynı değere ayarlarken, initialize(from:count:) başka bir arabellekten kopyalar. Her ikisi de aralığı tamamen başlattığından okumak güvenlidir.
let dst = UnsafeMutablePointer<Int>.allocate(capacity: 4)
dst.initialize(repeating: 5, count: 4)
print(dst[3]) // 5
dst.deinitialize(count: 4)
dst.deallocate()Salt okunur ve değiştirilebilir
Verileri yalnızca inceleyen bir işlev UnsafePointer<T> almalı, verileri değiştiren bir işlev ise UnsafeMutablePointer<T> almalıdır. Değiştirilebilir bir işaretçi örtük olarak salt okunur işaretçiye dönüştürülebilir, ancak tersi mümkün değildir — bu, arayüz sınırında amacı zorunlu kılar.
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 directlyYerel değişkenler için withUnsafePointer
Bellek ayırmadan mevcut bir değere geçici işaretçi almak için withUnsafePointer(to:) veya bunun değiştirilebilir biçimini kullanın. İşaretçi yalnızca kapanışın içinde geçerlidir — hiçbir zaman dışarı kaçmasına izin vermeyin.
var value = 100
withUnsafeMutablePointer(to: &value) { ptr in
ptr.pointee += 1
}
print(value) // 101Yaygın tuzaklar
Türlendirilmiş işaretçiler güçlüdür ancak hatayı affetmez:
initializeişleminden öncepointeeokumak tanımsızdır.- Kaynak tutan türlerde
deinitializeişlemini unutmak sızıntıya yol açar. - Bir
withUnsafePointerişaretçisinin dışarı kaçmasına izin vermek sarkan bir işaretçi oluşturur.
Derleyici burada size güvenir — çalışma zamanında koruma mekanizmaları yoktur.
// DANGEROUS — pointer escapes the closure
// var escaped: UnsafePointer<Int>?
// withUnsafePointer(to: &x) { escaped = $0 }
// escaped!.pointee // dangling, undefined behaviorKüçük bir elle yönetilen yığın
Hepsini bir araya getirelim: bir blok ayırın, dizinlemeyle öğeler olarak kullanın ve ardından temizleyin. Bu, özel koleksiyonların ve C ile birlikte çalışmanın temelidir.
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()Hızlı kontrol
Doğru işaretçi yaşam döngüsünü hatırlayın.
Özet
Artık türlendirilmiş işaretçileri biliyorsunuz:
UnsafePointerokur,UnsafeMutablePointerise okur ve yazar.pointeedeğere erişir; aritmetik öğe birimleriyle yapılır.- Yaşam döngüsü allocate → initialize → use → deinitialize → deallocate şeklindedir ve ideal olarak
deferile güvence altına alınır.
Sonraki bölümde, arabellek işaretçilerinin bitişik bir bölgenin tamamını koleksiyonlarla uyumlu bir arayüzle nasıl sardığını göreceksiniz.
Sıkça Sorulan Sorular
“UnsafePointer ve UnsafeMutablePointer” dersi ücretsiz mi?
Evet — “UnsafePointer ve UnsafeMutablePointer” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Swift Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Swift Academy kursu toplamda 4 dersten oluşur.
“UnsafePointer ve UnsafeMutablePointer” dersinde ne öğreneceğim?
Ham belleği dikkatle okuyun ve yazın. Swift Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
Swift Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Swift Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.
“UnsafePointer ve UnsafeMutablePointer” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu Swift Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Swift Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- MemoryLayout ve Hizalama
- UnsafePointer ve UnsafeMutablePointer
- Güvenli Olmayan Tampon İşaretçileri
- withUnsafeBytes ve C Birlikte Çalışabilirliği