Swift
Key-Value Observation
KVO
iOS Development
Swift Programming

Is key-value observation KVO available in Swift?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Yes, KVO is available in Swift, but it is not a general-purpose feature for every Swift type. KVO comes from the Objective-C runtime, so it works best with NSObject-based classes and properties that are exposed to Objective-C dynamic dispatch. That is why some Swift code supports KVO cleanly while pure Swift structs and many value types do not.

KVO Works Through Objective-C Runtime Features

To make a Swift property observable by KVO, the observed object usually needs to inherit from NSObject, and the property needs Objective-C-compatible dispatch.

swift
1import Foundation
2
3final class Account: NSObject {
4    @objc dynamic var balance: Double = 0
5}

The @objc dynamic combination is what makes KVO possible here. Without it, the property may compile and work normally in Swift, but not participate in KVO.

Observe with Swift Key-Path API

Modern Swift KVO usually uses the typed observe API instead of the older string-based Objective-C interface.

swift
1import Foundation
2
3final class Account: NSObject {
4    @objc dynamic var balance: Double = 0
5}
6
7let account = Account()
8
9let observation = account.observe(\.balance, options: [.old, .new]) { object, change in
10    print("old:", change.oldValue ?? 0)
11    print("new:", change.newValue ?? 0)
12}
13
14account.balance = 125.0

The returned observation token must be kept alive. If it is deallocated immediately, observation stops.

What Does Not Work Well

KVO is not a universal observation system for native Swift types. It does not naturally apply to:

  • structs
  • enums
  • many pure Swift classes without NSObject
  • stored properties that are not exposed to Objective-C runtime dispatch

That is why developers sometimes think "KVO is broken in Swift" when the real issue is that they are using a type model outside KVO's design.

KVO Is Still Useful, but It Is Not the Only Option

KVO remains relevant when integrating with Cocoa APIs and existing Objective-C-based frameworks. It is especially common with Foundation and AppKit or UIKit classes that were designed around observation patterns long before Swift existed.

For new app architecture, though, Swift often offers cleaner alternatives:

  1. property observers such as didSet
  2. delegates and callbacks
  3. Combine publishers
  4. SwiftUI state bindings

Those patterns are often easier to reason about in all-Swift code.

Common Memory and Lifecycle Concerns

Observation only works as long as the observer token exists. In a controller or view model, store the token in a property:

swift
1import Foundation
2
3final class Account: NSObject {
4    @objc dynamic var balance: Double = 0
5}
6
7final class AccountWatcher {
8    private var observation: NSKeyValueObservation?
9
10    func start(account: Account) {
11        observation = account.observe(\.balance, options: [.new]) { _, change in
12            print(change.newValue ?? 0)
13        }
14    }
15}

This avoids the common mistake of creating an observation inline and then losing it immediately.

Choose KVO Only When It Fits the Boundary

If you are interacting with Objective-C framework classes, KVO can be the right tool. If you are designing a fresh Swift module, forcing KVO into the model layer is often a sign that another observation mechanism would be cleaner and more type-safe.

The key point is not "Swift has KVO" or "Swift does not have KVO". The key point is that Swift can use KVO where Objective-C runtime participation exists.

Common Pitfalls

  • Trying to use KVO on structs or other pure value types.
  • Forgetting @objc dynamic on properties meant to be observed.
  • Not inheriting from NSObject when using classic KVO patterns.
  • Dropping the NSKeyValueObservation token and accidentally stopping observation.
  • Using KVO in brand-new Swift code when simpler native observation tools would be clearer.

Summary

  • KVO is available in Swift, but mainly through NSObject and Objective-C runtime support.
  • Use @objc dynamic on observed properties that should participate in KVO.
  • Prefer the Swift key-path observe API over old string-based observation.
  • Keep the observation token alive for as long as observation should continue.
  • For pure Swift designs, consider delegates, property observers, Combine, or SwiftUI state instead.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.