KVO: Swift's Built-In Observer Pattern
KVO lets an object subscribe to property changes on another object automatically. It shines when you need UI updates driven by model state, but forgetting to remove observers before deallocation crashes your app with an NSException.
Why it exists
Before SwiftUI and Combine, UIKit needed a way to react to data changes without tight coupling. Delegation works for one-to-one relationships, but what if many objects care about a single property? KVO was created to give any object the ability to subscribe to changes on another object's properties through the Objective-C runtime, enabling one-to-many automatic propagation without the observed object knowing who is listening.
The mental model
Think of KVO like a doorbell system. The house does not know who is standing outside, but when someone presses the button by changing a property, the bell rings and every listener registered to that circuit gets notified. The house did not plan for any specific visitor; it just exposes a signal that the wiring carries to whoever subscribed.
How it works
To observe a property, the observer calls addObserver on the target for a key path. The target must be an NSObject subclass and the observed property must be marked dynamic or belong to a class where the Objective-C runtime can swizzle the setter. When the setter fires, the runtime dispatches observeValue to every registered observer with change details including old and new values. In modern Swift, you can also use the observe method which returns an NSKeyValueObservation token. Keeping that token alive retains the subscription, and letting it deallocate removes the observer automatically.
When to use it
Reach for KVO when you need loose, one-to-many observation of property changes on NSObject-based classes and you cannot modify the source class to add a delegate protocol. Common scenarios include observing system objects like OperationQueue, URLSessionTask, or AVPlayer properties such as isFinished or status where Apple provides KVO compliance but no Swift-native async stream.
When not to use it
Do not use KVO on pure Swift structs or classes that do not inherit from NSObject. Do not use it when you own both sides of the relationship and can use a simple closure, delegate, or Combine publisher instead. Avoid it if your team values type safety, because key paths in the old API are stringly typed and runtime mismatches throw exceptions. If you need complex coordination of multiple changing values, KVO's single-property granularity becomes verbose and error-prone.
One canonical example
A download manager wraps a URLSessionTask. The view controller needs to update a progress bar as bytes download. Instead of polling or inventing a delegate protocol for a system class, the view controller calls task.progress.addObserver and implements observeValue. When bytes transfer, the UI updates automatically. The footgun appears if the view controller deallocates without removing itself; the next progress update messages a zombie and the app crashes.
Interview question
Your view controller needs to update a progress bar as a URLSessionTask downloads bytes. Which observation strategy is most appropriate?
- a.Poll the progress property with a Timer because URLSessionTask prevents external observation of its state
- b.Use the delegate pattern because URLSessionTask provides a delegate callback for every byte transferred
- c.Use a Combine publisher because URLSessionTask exposes its progress as an @Published property
- d.Use KVO because URLSessionTask is a system NSObject class you cannot modify to add your own delegate protocolCorrect
Why? this is the answer
KVO is intended for observing properties on system NSObject subclasses like URLSessionTask that you cannot alter to add delegates. Option B is tempting because UIKit relies heavily on delegation, but URLSessionTask does not offer a dedicated progress delegate callback, which is why KVO is the canonical choice.
Just read this? Test yourself on what you have been reading.
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.
See open roles