NotificationCenter, delegate, closure or KVO: how do you choose?
Predict first
Which fits “tell several unrelated screens that the user logged out”?
// A: NotificationCenter
// B: a delegate
// C: a completion closure
- A
- B
- C
Mental model. A delegate is a phone call, a closure is a postcard reply, and a notification is a town crier.
Ask how many listeners and how much do they need to know each other. NotificationCenter is one-to-many with no knowledge of who listens: good for app-wide facts (user logged out, locale changed) and system events. A delegate is one-to-one with a typed contract and lets the receiver shape behaviour (“should I allow this?”). A closure suits a one-off result such as a completion. KVO watches one property on one object.
The price of notifications is invisibility: nothing in the type system says who reacts, so flows become hard to trace and test. Use them for broadcast facts, not for control flow you could express with a direct call.
It is a broadcast fact with many unknown listeners, which is what the notification center is for.
| NotificationCenter | Delegate | Closure | KVO | |
|---|---|---|---|---|
| Receivers | many | one | one | many |
| Coupling | a name string | a protocol | a closure type | a key path |
| Typed payload | no | yes | yes | yes |
| Best for | app-wide broadcasts | customising behaviour | one-off results | watching one property |
Common traps
- Using notifications as a service locator. Posting to call a specific object is a delegate in disguise.
- Several observers of one event with shared state. Order is undefined, so they must not depend on each other.
They might follow up with
- What replaces these in new code?
AsyncStreamand Combine publishers for streams, and Observation for UI state. - How do you test code that posts notifications? Inject a private
NotificationCenter()instead of using.default.
Related questions
- 2.4.1 How does NotificationCenter deliver a notification, and on which thread?
- 2.4.5 How does KVO work in Swift, and why does it sometimes never fire?
← How do you pass data in a notification safely? How does KVO work in Swift, and why does it sometimes never fire? →