How can I make a weak protocol reference in 'pure' Swift without objc
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
You can create weak protocol references in pure Swift, but only when the protocol is restricted to class types. The key is to make the protocol inherit from AnyObject, because ARC only manages reference types and weak only applies to objects.
Make the Protocol Class-Only
If a protocol can be adopted by a struct or enum, Swift has no object reference to weaken. That is why the first step is to add an AnyObject constraint.
This is the simplest and most common answer. In many designs, a plain weak var delegate: SomeProtocol? is enough, and you do not need wrappers or type erasure.
Store Multiple Weak Protocol References
The question becomes harder when you want a collection of delegates. An array keeps strong references to its elements, so storing protocol values directly will prevent deallocation. In that case, create a wrapper that owns only a weak reference.
This pattern is useful for multicast delegates, event hubs, and observer lists. The wrapper exists only to break strong ownership. The actual protocol type still defines the behavior.
When a Generic Weak Box Helps
If you need the same weak-storage pattern in many places, a generic box is a cleaner tool:
For ordinary classes, WeakBox is straightforward. For protocols, dedicated wrappers are often easier to read because protocol existentials and generics can get awkward, especially when the compiler asks for any SomeProtocol.
The design rule is simple:
- Use a plain weak property for one delegate.
- Use a wrapper for arrays or dictionaries of delegates.
- Keep the protocol class-only with
AnyObject.
Common Pitfalls
The most common mistake is forgetting the class constraint. If the protocol does not inherit from AnyObject, Swift will reject weak var observer: MyProtocol? because the protocol might be implemented by a value type.
Another mistake is assuming a collection of protocol values is weak just because the property holding the collection is weak. It is not. The array itself may be weakly referenced, but the array still strongly retains its contents. That is why each element needs its own weak wrapper.
A subtler bug appears when the referenced object has no strong owner anywhere else. If the only reference is weak, the instance is deallocated immediately. That is expected ARC behavior, not a compiler bug. Make sure some other part of the program owns the delegate for as long as it should stay alive.
Finally, avoid reaching for @objc unless you need Objective-C runtime features such as optional protocol methods or NSHashTable. Pure Swift works well here as long as you model ownership correctly.
Summary
- Weak protocol references are possible in pure Swift when the protocol inherits from
AnyObject. - A single delegate usually needs only
weak var delegate: SomeProtocol?. - Collections of delegates need per-item weak wrappers, because arrays store elements strongly.
- '
weakonly works with reference types managed by ARC, not with structs or enums.' - If an object disappears immediately, check whether any strong reference is keeping it alive.

