0Pricing
Swift Academy · Ders

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)   // 99

Bellek 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 element

Initialize 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 directly

Yerel 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) // 101

Yaygın tuzaklar

Türlendirilmiş işaretçiler güçlüdür ancak hatayı affetmez:

  • initialize işleminden önce pointee okumak tanımsızdır.
  • Kaynak tutan türlerde deinitialize işlemini unutmak sızıntıya yol açar.
  • Bir withUnsafePointer iş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 behavior

Küçü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:

  • UnsafePointer okur, UnsafeMutablePointer ise okur ve yazar.
  • pointee değere erişir; aritmetik öğe birimleriyle yapılır.
  • Yaşam döngüsü allocate → initialize → use → deinitialize → deallocate şeklindedir ve ideal olarak defer ile 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

  1. MemoryLayout ve Hizalama
  2. UnsafePointer ve UnsafeMutablePointer
  3. Güvenli Olmayan Tampon İşaretçileri
  4. withUnsafeBytes ve C Birlikte Çalışabilirliği
← Swift Academy Sayfasına Dön