ProgrammatieiOS ontwikkelaar

Hoe werkt dynamische aanroep van methoden in Swift? Welke mechanismen (zoals @objc, dynamic, AnyObject) maken het mogelijk om methoden op naam aan te roepen tijdens runtime, en onder welke voorwaarden is dit mogelijk? Geef een voorbeeld van gebruik.

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

Dynamische aanroep van methoden is de mogelijkheid om methoden op naam aan te roepen tijdens runtime, en niet tijdens compilatie. In Swift is dit mogelijk door interactie met de Objective-C runtime via de modifiers @objc en dynamic, of door het gebruik van het protocol AnyObject.

Mechanismen:

  • @objc — markeert een methode/eigenschap/klasse voor export naar de Objective-C runtime.
  • dynamic — vereist dat de aanroep plaatsvindt via de Objective-C message dispatch, en niet via een statische aanroep (vtable).
  • Het protocol AnyObject maakt het mogelijk om methoden als optioneel te verklaren en deze aan te roepen via optional chaining.

Beperkingen:

  • Werkt alleen met klassen die van NSObject erven, of met protocollen die gemarkeerd zijn als @objc.
  • Betreft alleen methoden/eigenschappen met het attribuut @objc of gemarkeerd door erfelijkheid van NSObject.

Voorbeeld:

import Foundation class Person: NSObject { @objc dynamic func sayHello() -> String { return "Hello!" } } let person = Person() // Dynamische aanroep via Selector (perform:): if person.responds(to: #selector(Person.sayHello)) { if let result = person.perform(#selector(Person.sayHello))?.takeUnretainedValue() as? String { print(result) // "Hello!" } }

Evenzo kunnen functies worden aangeroepen via AnyObject met optional chaining:

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

Vragend met een val

Kan een struct dynamische aanroep van methoden ondersteunen via @objc, dynamic of AnyObject?

Antwoord: Nee, alleen klassen die van NSObject erven, of klassen/protocollen met de modifier @objc kunnen dergelijke mechanismen ondersteunen. Structs en enums zijn niet compatibel met de Objective-C runtime, daarom kunnen ze geen dynamische deelnemers zijn.


Voorbeelden van echte fouten door onbekendheid met de subtiliteiten van het thema


Verhaal

In het project werd een @objc protocol gebruikt voor de delegate. Een van de ontwikkelaars verwijderde de erfelijkheid van de delegate-klasse van NSObject, waardoor de optionele methoden niet meer bereikbaar waren via optional chaining. De architectuur stopte met werken, en tests begonnen constant te falen.


Verhaal

In een poging om KVO (key-value observing) op een eigenschap van de struct te gebruiken, markeerde de ontwikkelaar deze als dynamic. De code compileerde, maar werkte niet zoals verwacht, omdat structs de Objective-C runtime niet ondersteunen. Dynamische reacties op wijzigingen werkten niet, wat leidde tot gemiste UI-updates.


Verhaal

In de extensie van de klasse vergaten ze de modifier @objc toe te voegen aan de functie die ze aanriepen via perform(_:). Hierdoor traden er crashes op in productie bij de poging om een ongerelateerde selector aan te roepen. De oorzaak werd lang gezocht, totdat ze het ontbreken van de export van de functie naar Objective-C opmerkten.