Swift
Protocols
AnyObject
Class-Only Protocol
Swift Programming

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.

Browse interview questions

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.

swift
protocol ImageLoaderDelegate: AnyObject {
    func didFinishLoading()
}

That excludes structs and enums. A class can conform, but a value type cannot.

swift
1class LoaderOwner: ImageLoaderDelegate {
2    func didFinishLoading() {
3        print("done")
4    }
5}

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.

swift
1protocol DownloadDelegate: AnyObject {
2    func didCompleteDownload()
3}
4
5class Downloader {
6    weak var delegate: DownloadDelegate?
7}

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.

swift
protocol Renderable: AnyObject {
    func render()
}

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 AnyObject is 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.
  • 'AnyObject does not imply NSObject or Objective-C behavior by itself.'
  • Add the restriction only when reference semantics are actually required.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track 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.

Browse interview questions