ProgramlamaiOS geliştirici

Swift'te Property Wrappers nedir? Nasıl çalışırlar, ne için kullanılırlar, hangi sınırlamalar ve olanaklar mevcuttur? Özel property wrapper oluşturma ve uygulama örneği verin.

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

Property Wrappers - özelliklerle (örneğin, doğrulama, değişiklikler veya belirli bir şekilde depolama) çalışma mantığını kapsüllemeyi ve bunu kod üzerindeki notasyonlar aracılığıyla çeşitli özellikler için yeniden kullanılmasını sağlayan bir mekanizmadır. Tekrarlayan koddan kurtulmanıza ve okunabilirliği artırmanıza yardımcı olurlar.

Property Wrapper, @propertyWrapper notasyonu ile property wrapper protokolünü uygulayan bir yapı, sınıf veya enum’dur ve zorunlu wrappedValue özelliğine sahiptir.

Sınırlamalar ve incelikler:

  • Property Wrapper, hesaplanmış (computed) özelliklere uygulanamaz.
  • Wrapper'ı başlatırken argümanların iletilmesi kısıtlanabilir.
  • Yapı içinde birden çok sarılmış (wrapped) özellik kullanıldığında yalnızca value type ile düzgün çalışır.

Örnek: Değer aralığını otomatik olarak sınırlayan bir property wrapper (Clamped) yazalım.

@propertyWrapper struct Clamped<Value: Comparable> { var value: Value let range: ClosedRange<Value> var wrappedValue: Value { get { value } set { value = min(max(newValue, range.lowerBound), range.upperBound) } } init(wrappedValue initialValue: Value, _ range: ClosedRange<Value>) { self.range = range self.value = min(max(initialValue, range.lowerBound), range.upperBound) } } struct Person { @Clamped(0...120) var age: Int = 25 } var p = Person() p.age = 200 // Artık p.age = 120 p.age = -10 // Artık p.age = 0

Kandırıcı soru

Dışarıdan erişim sağlamak için bir property wrapper nesnesine hangi yol ile erişilebilir?

Cevap: Özelliğin alt çizgisi ile adı aracılığıyla (_). Örneğin, özellik age adını taşıyorsa, property wrapper nesnesine _age olarak erişilebilir:

var p = Person() let wrapper = p._age // bu Clamped<Int> tipidir

Bilgi eksikliğinden kaynaklanan gerçek hata örnekleri


Hikaye

UserDefaults için bir depolama projesinde, ilkel türlerle çalışan özel bir property wrapper uygulandı. Bunu referans türler (class) için kullanırken beklenmedik bir bellek sızıntısı ortaya çıktı - property wrapper, nesne üzerinde güçlü bir referans tutuyordu, bu da güçlü bir döngü ve veri sızıntısına yol açıyordu. Hata, sarmalayıcı içinde zayıf/temiz referansa geçilerek düzeltildi.


Hikaye

Proje, property wrapper'ı hesaplanmış (computed) özelliklere uygulamaya çalıştı, ancak derleyici şu hatayı verdi: property wrapper yalnızca depolanan özelliklerle (stored property) kullanılabilir. Bu durumu gözden kaçırmak, modülün geliştirilmesini 2 gün geciktirdi.


Hikaye

Sarmalayıcı yapı oluşturulurken init(wrappedValue:...) üzerinden doğru başlatma sözdizimi uygulanmayı unuttuk. Sonuç olarak, property wrapper aracılığıyla varsayılan değerler yapılamıyordu, bu da sarmalayıcı büyük sayıda modelde entegre edildikten sonra ortaya çıktı. Mimarinin gözden geçirilmesi gerekti.