Delegates in swift?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Delegation is one of the most common communication patterns in Swift, especially in UIKit and AppKit code. It lets one object announce events or ask for decisions without tightly coupling itself to a specific implementation.
What a Delegate Actually Does
A delegate is another object that receives callbacks from the object doing the work. In Swift, the pattern is usually built with a protocol, a delegate property, and one or more methods that describe the messages being sent.
This design keeps responsibilities separate. A reusable component can focus on its own job, while another object decides how to respond to events. A table view, for example, knows when a row was selected, but it delegates the response to another object.
The pattern has three recurring pieces:
- a protocol that defines the callback methods
- a delegate property, usually marked
weak - a class that adopts the protocol and handles the event
Building a Simple Delegate in Swift
The example below works in a Swift playground or command-line project. Counter performs a task, and Logger reacts whenever the value changes.
A few details are worth noticing. The protocol inherits from AnyObject, which allows the delegate reference to be weak. That matters because delegates are often long-lived UI controllers, and a strong reference can create a retain cycle.
The Counter class also does not know anything about Logger. It only knows that the delegate conforms to CounterDelegate. That decoupling is the main reason delegation stays useful even in codebases that also use closures, Combine, or async streams.
When Delegates Are a Good Fit
Delegates work well when one object owns a process and another object needs structured callbacks over time. They are especially useful when:
- multiple related callbacks belong together
- the sender should remain reusable and framework-like
- the receiver needs context from the sender
- communication is one-to-one rather than broadcast
That is why Apple uses delegates heavily in views, controllers, networking APIs, and data pickers. A single delegate can answer several questions and react to several events without the sender knowing app-specific details.
Closures can be a better fit for one-off callbacks. Delegates are usually better when the communication is ongoing and has a small protocol-shaped surface.
Common Pitfalls
- Forgetting
weakon the delegate property. If both objects strongly reference each other, neither will be released. - Omitting
AnyObjectfrom the protocol when you intend to use a weak reference. Only class-bound protocols can be referenced weakly. - Letting the delegate disappear too early. If the delegate object is deallocated, callbacks stop because the weak reference becomes
nil. - Putting too much app logic in the sender. The sender should report events, not become tightly coupled to one screen or workflow.
- Using delegates for simple one-time results where a closure would be clearer and easier to read.
Summary
- A delegate is an object that receives callbacks from another object through a protocol.
- In Swift, delegation is usually implemented with a protocol plus a
weakdelegate property. - The pattern helps keep reusable components decoupled from app-specific behavior.
- Add
AnyObjectto delegate protocols when the delegate should be held weakly. - Use delegates for ongoing structured callbacks, and prefer closures for simpler one-off responses.

