A declaration cannot be both 'final' and 'dynamic' error in Swift 1.2
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
This Swift error happens because final and dynamic ask the compiler to do opposite things. final says the declaration should not participate in override-based dynamic dispatch, while dynamic says dispatch should go through the Objective-C runtime dynamically. Swift rejects the combination because the two modifiers are fundamentally incompatible.
What final Means
When a class member is marked final, Swift knows it cannot be overridden in a subclass. That gives the compiler freedom to use direct dispatch and other optimizations.
For example:
Here render is fixed. Subclasses may inherit it, but they cannot override it.
What dynamic Means
dynamic tells Swift to use Objective-C-style dynamic dispatch for that declaration. It is usually associated with cases where runtime behavior matters, such as:
- KVO
- method swizzling
- Objective-C runtime messaging
For example:
The dynamic behavior is specifically about runtime message dispatch, not compile-time locking of the implementation.
Why the Two Keywords Conflict
Now consider this invalid declaration:
Swift rejects it because:
- '
finalsays no runtime override-style flexibility is needed' - '
dynamicsays route this through dynamic Objective-C dispatch'
You are asking for both less dynamism and more dynamism at the same time. The compiler cannot satisfy both intent signals meaningfully, so it reports the error.
Choose the Modifier That Matches the Real Requirement
If the declaration must support Objective-C runtime features, use dynamic and remove final:
If the real goal is to prevent overriding and keep dispatch as direct as possible, use final and remove dynamic:
The right answer depends on why the declaration had those modifiers in the first place.
Common Real-World Cases
For KVO or Objective-C runtime integration, dynamic is usually the one you actually need. For internal Swift-only methods where you want to lock down behavior and communicate intent, final is usually the better choice.
This often shows up during refactoring. A developer may add final broadly for design or performance reasons and later add dynamic for runtime behavior without realizing the two are incompatible.
Do Not Optimize Blindly
Historically, some developers added final aggressively because they wanted performance improvements. Others added dynamic because an Objective-C feature seemed to require it. In both cases, the modifier should reflect a real semantic need, not a cargo-cult rule.
If you are working in Swift-only code with no runtime magic involved, dynamic is usually unnecessary. If you need Objective-C runtime participation, then final is usually the wrong modifier for that declaration.
Common Pitfalls
The most common mistake is assuming final and dynamic are both “good” modifiers and can therefore be combined. They are not additive in that way.
Another pitfall is forgetting that dynamic is tied to runtime dispatch semantics rather than normal Swift method calls. If the code does not need Objective-C runtime behavior, dynamic is often the wrong tool.
It is also easy to over-apply final during refactors and then hit this error only later when a property or method needs KVO or similar runtime behavior.
Finally, do not pick a modifier only because of a vague performance or interoperability instinct. Start from the actual requirement and the correct modifier usually becomes obvious.
Summary
- '
finalanddynamicconflict because they express opposite dispatch intentions.' - Use
finalwhen you want to prevent overriding and keep the declaration fixed. - Use
dynamicwhen Objective-C runtime dispatch is required. - Remove one of the modifiers based on the real semantic need.
- This is a design conflict in the declaration, not a strange Swift parser bug.
Related reading
- A failure occurred while executing com.android.build.gradle.internal.tasks
- A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
- Abstract classes in Swift Language
- Abstract functions in Swift Language
- A fatal error occurred. The folder /usr/share/dotnet/host/fxr does not exist
- A good solution for await in try/catch/finally?
- Access Asset Catalog programmatically
- Access Container View Controller from Parent iOS
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseNo course covers this one yet
Basis Lab writes one for you from a sentence about what you want to be able to do, then teaches it and checks you understood. Your first course is free.
Build my courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.