What's the difference between a protocol extended from AnyObject and a class-only protocol?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
In modern Swift, these two ideas are effectively the same. Declaring a protocol that inherits from AnyObject is how you make it class-only. In other words, a protocol "extended from AnyObject" is the language mechanism for declaring a class-only protocol. The confusion usually comes from older Swift terminology rather than from a real semantic difference.
What AnyObject Means in a Protocol Declaration
When a protocol inherits from AnyObject, only class types may adopt it.
That excludes structs and enums. A class can conform, but a value type cannot.
Trying to make a struct conform would fail because the protocol is class-only.
Why Class-Only Restrictions Exist
The most common reason is weak references. weak applies only to reference types, so delegate protocols are often restricted to classes.
Without the AnyObject restriction, the compiler could not guarantee that delegate refers to a class instance eligible for weak storage.
There Is No Separate Modern Feature
Older discussions often say "class-only protocol" as if it were a different declaration form. In current Swift, the usual way to express that idea is simply protocol P: AnyObject.
So these phrases mean the same thing in practice:
- protocol inheriting from
AnyObject - class-only protocol
They describe one concept, not two different protocol categories.
What This Does Not Mean
Restricting a protocol to classes does not automatically make it inherit behavior from NSObject, and it does not imply Objective-C interoperability by itself.
This only says conformers must be class instances. It does not say anything about Objective-C runtime features, KVO, or Foundation inheritance.
If you need Objective-C exposure, that is a separate decision involving @objc or NSObjectProtocol depending on the use case.
Use It When Reference Semantics Matter
Class-only protocols are a good fit when your design depends on identity or shared mutable state rather than copy semantics. Common cases include:
- delegates stored weakly
- observer references
- APIs that depend on object identity
- mutation flows built around shared reference semantics
If value types should also be allowed to conform, do not add the AnyObject restriction.
This is why many code reviews treat AnyObject as a semantic signal rather than mere syntax. It tells the reader that the protocol is expected to participate in reference-oriented relationships such as delegation, identity checks, or weak storage, not just generic polymorphism.
That is why newer Swift code usually uses the AnyObject form directly. It is the clear, modern spelling of the old “class-only” idea, so it tends to reduce ambiguity rather than add it.
Common Pitfalls
The biggest mistake is assuming AnyObject and "class-only protocol" are different mechanisms in modern Swift. They are the same practical concept.
Another issue is adding AnyObject by habit even when the protocol should logically allow structs and enums. That unnecessarily narrows the design and blocks value-type conformance.
People also sometimes confuse AnyObject with NSObject. A class-only Swift protocol does not automatically mean Foundation inheritance or Objective-C behavior.
Finally, if the real reason for the restriction is weak storage, make that design intent clear. Otherwise the AnyObject constraint can look arbitrary to future readers.
Summary
- In modern Swift, a protocol inheriting from
AnyObjectis how you declare a class-only protocol. - There is no meaningful semantic difference between those two phrases.
- The restriction is most commonly used for weak delegates and other reference-only relationships.
- '
AnyObjectdoes not implyNSObjector Objective-C behavior by itself.' - Add the restriction only when reference semantics are actually required.
Related reading
- What's the difference between Architectures and Valid Architectures in Xcode Build Settings?
- What's the difference between commit and apply in SharedPreferences
- What's the difference between fill_parent and wrap_content?
- What's the difference between setWebViewClient vs. setWebChromeClient?
- What's the difference between src/androidtest and src/test folders?
- What's the difference between the various methods to get an Android Context?
- What's the difference between 'weak' and 'assign' in delegate property declaration
- What's the dSYM and how to use it? iOS SDK
.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 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.