Skip to content
tezvyn:
Menu

The dynamic keyword and message dispatch

Source: interviewHardHow cards are made

Summary

dispatch mechanisms and ObjC runtime.

Key points

dynamic forces Objective-C message dispatch via objc_msgSend, enabling KVO and swizzling, at the cost of skipping inlining and devirtualization.

What's really being asked

It probes whether you understand Swift's four dispatch styles and the precise role dynamic plays in Objective-C runtime features.

Swift dispatch background

Swift uses inline or static dispatch for many calls, vtable dispatch for non-final class methods, witness-table dispatch for protocol requirements, and Objective-C message dispatch when needed. The compiler prefers the fastest option that preserves correctness, inlining and devirtualizing aggressively.

What dynamic does

Marking a member dynamic forces it through the Objective-C messaging path, objc_msgSend, every time, even when the compiler could otherwise resolve it statically. Because objc_msgSend looks the selector up at runtime, the implementation can be replaced or intercepted, which is exactly what enables Key-Value Observing, which swizzles setters, and manual method swizzling. dynamic usually appears together with @objc, since the member must be visible to the Objective-C runtime; @objc alone exposes the member but does not by itself force dynamic dispatch in all cases.

Performance trade-offs

Message dispatch cannot be inlined or devirtualized and carries per-call lookup overhead. In a tight loop this is measurable. Static and inline dispatch let the optimizer fold and specialize code. So dynamic is a deliberate trade of speed for runtime flexibility, used sparingly.

The mistakes people make

Saying dynamic is just polymorphism or method overriding, which vtable dispatch already provides. Conflating dynamic with @objc; they are related but not identical. Claiming dynamic improves performance.

What usually comes next

How does KVO use dynamic? What is the difference between dynamic and final? When does Swift use witness tables? How does the optimizer devirtualize a non-final method?

A concrete example

You want KVO on a Swift property progress. You declare @objc dynamic var progress: Double. The dynamic attribute routes the setter through objc_msgSend so the KVO machinery can swizzle it and emit change notifications. If you drop dynamic, observers never fire because the call is dispatched statically and bypasses the runtime hook.

Interview question

A Swift property declared @objc but not dynamic fails to deliver KVO change notifications. What is the underlying reason?

  • a.@objc already forces objc_msgSend, so KVO should work and the bug is elsewhere
  • b.Without dynamic the setter can be dispatched statically, bypassing the runtime hook KVO swizzles intoCorrect
  • c.dynamic only affects read access, so adding it would not help notifications
  • d.KVO does not require any special dispatch and works on plain Swift properties
Why?

KVO relies on intercepting the setter through Objective-C message dispatch; only dynamic guarantees that path. @objc exposes the member but does not force every call through objc_msgSend.

Just read this? Test yourself on what you have been reading.

Read the original → docs.swift.org

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on swift — each one lists the topics its interview covers.

See open roles