@dynamicMemberLookup — Swift'te, bir nesnenin özelliklerine çalışma zamanında erişimi override etmenizi sağlayan bir notasyon. Bu mekanizma tarihsel olarak, Python gibi dinamik dillerle daha şeffaf bir entegrasyon sağlamak için tanıtılmıştır ve ayrıca proxy nesnelerde, dinamik modellerde ve DSL'lerde verilere erişim yönlendirmesini daha esnek hale getirmeyi amaçlamaktadır.
Sorun: Standart Swift, özellikleri açıkça tanımlamanızı gerektirir ve varlıklarını derleme zamanında kontrol eder. Fakat bazen, derleme zamanında var olmayan isimler üzerinden özelliklere erişme ihtiyacı vardır; örneğin, JSON, API, proxy nesneler veya script sarmalayıcıları ile çalışırken.
Çözüm: @dynamicMemberLookup kullanmak ve var olmayan özelliklere erişim girişimlerini yakalamak için subscript(dynamicMember:) uygulamak.
Kod örneği:
@dynamicMemberLookup struct JSON { private var data: [String: Any] subscript(dynamicMember member: String) -> Any? { data[member] } } let user = JSON(data: ["name": "Anna", "age": 23]) print(user.name as? String) // Anna
Anahtar özellikler:
DynamicMemberLookup'u sadece struct için mi yoksa sınıflar için de uygulamak mümkün mü?
Evet, bu mekanizma sınıflar, struct ve enum (Swift 5+’ten itibaren) için uygulanabilir. Önemli olan uygun subscript’i uygulamaktır.
DynamicMemberLookup aracılığıyla var olmayan bir özelliğe erişirsem ne olur?
Subscript’ten bir değer döner, değer eksikliğini işleme sorumluluğu sizin uygulamanıza aittir.
Örneğin, yukarıdaki örnekte user.secret'e erişirseniz, nil döner.
Farklı bir tür anahtarla, örneğin Int ile dinamik erişim sağlamak mümkün mü?
Evet! Farklı argument label’lara sahip subscript(dynamicMember:) tanımlayabilir ve normal subscript'lerle birleştirebilirsiniz.
@dynamicMemberLookup struct ArrayProxy { private let array: [Int] subscript(dynamicMember member: String) -> Int? { if member == "first" { return array.first } if member == "last" { return array.last } return nil } subscript(index: Int) -> Int? { array[safe: index] } }
Geliştirici, kullanıcı modeli (User) için @dynamicMemberLookup kullanarak herhangi bir alanı stringler aracılığıyla erişmeye çalışıyor. Kod şeffaflığını yitiriyor, IDE önerileri kayboluyor.
Avantajlar:
Dezavantajlar:
@dynamicMemberLookup, önceden bilinmeyen alanlara sahip bir JSON nesnesi ile çalışmak için uygulanmıştır. Mekanizma, biçimsiz verilerle şık ve güvenli bir şekilde (Any?/optional binding aracılığıyla) çalışmayı mümkün kılar.
Avantajlar:
Dezavantajlar: