Learn iOS Development

Restricting a Protocol to Classes in Swift

Deep Dive in to Why & How

Shashank Thakur
Mobile App Development Publication

--

How to Restrict a Protocol to Classes in Swift
Photo by Utsman Media on Unsplash

In Swift, protocols are a powerful feature that allows you to define a set of methods and properties that a conforming type must implement. By default, protocols can be adopted by both classes and structs. However, there are situations where you might want to restrict a protocol to be adopted only by classes. In this blog post, we’ll explore how to accomplish this and discuss the reasons why you might want to do so.

The Need for Class-Only Protocols

Before diving into the implementation, let’s understand why you might want to restrict a protocol to be adopted exclusively by classes.

  1. Inheritance: Class inheritance is a fundamental concept in object-oriented programming. If you have a protocol that represents a base behavior that should be inherited by subclasses, you want to ensure that only classes can conform to it.
  2. Reference Types: Classes are reference types, meaning that when you pass a class instance around, you’re working with a reference to the object rather than a copy. In certain scenarios, it’s essential to enforce that a type conforms to a protocol as a reference type.
  3. Objective-C Interoperability: If your Swift code needs to be interoperable with Objective-C, you might need to restrict a protocol to classes, as Objective-C doesn’t support struct or enum types.

Restricting a Protocol to Classes

In Swift, you can restrict a protocol to be adopted only by classes using the class keyword. Here's how you define a class-only protocol:

protocol MyClassOnlyProtocol: AnyObject {
// Protocol requirements go here
}

By adding the class keyword after the colon, you specify that this protocol can only be conformed to by class types. Now, let's see how you can use such a protocol.

Adopting a Class-Only Protocol

When you create a class-only protocol, only classes can conform to it. Attempting to make a struct or enum conform to it will result in a compiler error. Here’s an example:

protocol MyClassOnlyProtocol: AnyObject {
func myMethod()
}

// This class conforms to MyClassOnlyProtocol
class MyClass: MyClassOnlyProtocol {
func myMethod() {
print("Method implementation in MyClass")
}
}

// This will result in a compiler error:
// 'MyStruct' cannot conform to 'MyClassOnlyProtocol'; only classes can conform to class protocols
struct MyStruct: MyClassOnlyProtocol {
func myMethod() {
print("Method implementation in MyStruct")
}
}

As you can see, the MyStruct struct cannot conform to MyClassOnlyProtocol because it's restricted to class types.

When to Use Class-Only Protocols

Class-only protocols are particularly useful in scenarios where you need to enforce reference semantics, such as:

  1. Delegate Patterns: When defining delegate protocols, you typically want to ensure that delegate objects are classes to prevent unexpected behavior due to value types.
  2. Subclass Requirements: If you create a base class and want to guarantee that subclasses implement specific methods, you can use a class-only protocol to define those requirements.
  3. Interoperability: If your Swift code needs to interact with Objective-C, you might need class-only protocols to maintain compatibility with Objective-C’s reference-based memory management.

Conclusion

In Swift, you can restrict a protocol to be adopted only by classes by using the class keyword in the protocol definition. Class-only protocols are valuable when you want to enforce reference semantics, require specific inheritance hierarchies, or ensure interoperability with Objective-C. By understanding how to create and use class-only protocols, you can design your Swift codebase to be more expressive, maintainable, and robust.

--

--