ProgramlamaiOS geliştirici

Swift'te dinamik yöntem çağrısı nasıl çalışır? Hangi mekanizmalar (örneğin, @objc, dynamic, AnyObject) çalışma zamanında bir yöntem ismi ile çağrılmasına olanak tanır ve bu hangi koşullarda mümkündür? Bir kullanım örneği verin.

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

Cevap

Dinamik yöntem çağrısı, yöntemleri çalışma zamanında (runtime) ismi ile çağırma yeteneğidir, derleme zamanında değil. Swift'te bu, @objc ve dynamic modifikatörleri sayesinde Objective-C runtime ile etkileşim yoluyla mümkündür veya AnyObject protokolü kullanılarak yapılabilir.

Mekanizmalar:

  • @objc — bir yöntemi/özelliği/sınıfı Objective-C runtime'a dışa aktarmak için işaretler.
  • dynamic — çağrının statik çağrı (vtable tablosu) yerine Objective-C mesaj gönderimi ile gerçekleştirilmesini gerektirir.
  • AnyObject protokolü, yöntemlerin optional olarak tanımlanmasına izin verir ve optional chaining aracılığıyla çağrılmasına olanak sağlar.

Kısıtlamalar:

  • Sadece NSObject'tan türetilen sınıflarla veya @objc olarak işaretlenmiş protokollerle çalışır.
  • Sadece @objc niteliğine sahip veya NSObject'tan türemiş olarak işaretlenmiş yöntem/özelliklerle ilgilidir.

Örnek:

import Foundation class Person: NSObject { @objc dynamic func sayHello() -> String { return "Merhaba!" } } let person = Person() // Selector (perform:) aracılığıyla dinamik çağrı: if person.responds(to: #selector(Person.sayHello)) { if let result = person.perform(#selector(Person.sayHello))?.takeUnretainedValue() as? String { print(result) // "Merhaba!" } } }

Aynı şekilde, AnyObject aracılığıyla optional chaining ile işlevler çağrılabilir:

@objc protocol Greeter { @objc optional func greet() } class Robot: NSObject, Greeter { func greet() { print("Beep-beep!") } } let anyGreeter: AnyObject = Robot() anyGreeter.greet?() // "Beep-beep!"

Kandırmaca Sorusu

struct dinamik yöntem çağrısını @objc, dynamic veya AnyObject ile destekleyebilir mi?

Cevap: Hayır, yalnızca NSObject'tan türemiş sınıflar veya @objc modifikatörüne sahip olan sınıflar/protokoller bu tür mekanizmaları destekleyebilir. Struct ve enum'lar Objective-C runtime ile uyumlu değildir, bu nedenle dinamik katılımcılar olamazlar.


Konuyla ilgili bilgi eksikliğinden kaynaklanan gerçek hata örnekleri


Hikaye

Projede delegasyon için @objc protokolü kullanılıyordu. Geliştiricilerden biri delegasyon sınıfının NSObject'tan türemesini kaldırdı, bu nedenle optional yöntemler optional chaining ile çağrılamaz hale geldi. Mimari çalışmamaya başladı, testler sürekli başarısız oldu.


Hikaye

Geliştirici dinamik olarak işaret edildiği için bir yapının özelliği üzerinde KVO (key-value observing) kullanmaya çalıştı. Kod derlendi ama beklendiği gibi çalışmadı, çünkü struct Objective-C runtime'ı desteklemiyor. Değişikliklere dinamik tepki vermedi, bu da UI güncellemelerinin atlanmasına neden oldu.


Hikaye

Sınıf genişletmesinde, perform(_: aracılığıyla çağrılan işlevin @objc modifikatörünü eklemeyi unuttular. Sonuç olarak, ilişkili bir seçici çağrıldığında üretimde çökme yaşandı. Sebebi uzun süre arandı, ta ki işlevin Objective-C'ye dışa aktarılmadığı fark edilene kadar.