This article is a summary of my reading of Raywenderlich.com’s Design Patterns by Tutorials. The code in this article was modified according to my own ideas after READING the book. If you want to see the original book, please click the link to buy it.


The observer mode allows one object to observe changes in another object. In iOS, we typically use KVO for this.

The observer pattern consists of two main objects:

  • Subject: the object being observed.
  • Observer: Indicates the object to which the subject is observed.

When to use

We can use the observer mode when we want to keep track of an object’s changes.

A simple Demo

Create a User class that inherits NSObject:

@objcMembers class User: NSObject {
    dynamic var name: String
    public init(name: String) {
        self.name = name
    }
}
Copy the code

Starting with Swift 4, classes that inherit from NSObject do not automatically expose their properties to the Objective-C Runtime. Because NSObject uses objective-C Runtime to perform KVO, we manually add @objcMembers, which is equivalent to prefacing each property with @objc.

Dynamic means that the objective-C Runtime dynamically schedules the system to call getters and setters for properties, meaning that static or virtual calls will never be used. We have to add dynamic for KVO to work properly.

Let’s create a User instance and watch the name change:

let user = User(name: "Lebron")

var nameObservation: NSKeyValueObservation? =
    user.observe(\.name, options: [.initial, .new]) { (user, change) in
        print("The name is:\(user.name)")}// The name is Lebron
Copy the code

Here we use the Swift 4 KVO notation, \. Name is short for \KVOUser. Name, which is a KeyPath; The options parameter is used to specify what type of data you want to view. The [. Initial,.new] parameter is passed, which means that the value of name in the initial instance and the value of name in the change can be observed. The last parameter is the closure, which has two objects, user and change. User is the object after all changes are made. If the.new event is raised, change will contain an oldValue, oldValue.

In the options parameter, we passed.initial, so we can see the printed name is: Lebron.

If you try to change name to Love:

User. name = "Love" // The name is: LoveCopy the code

The console appears: the name is: Lebron. We have successfully observed the change of name.

In Swift 4’s KVO, we don’t need to manually remove the observer or closure, because the observer is weakly referenced and the closure is automatically removed when the observer becomes nil. In previous Versions of Swift or Objective-C, we had to call removeObserver to remove it, otherwise the application would crash when we accessed the reclaiming observer.

Although Swift 4’s KVO does not require us to manually remove the observation, the observed object must inherit from NSObject and use objective-C Runtime.