I have the following code in my Swift 4 project.
class DishesTableViewController : UITableViewController {
private var token :NSKeyValueObservation?
@objc dynamic private(set) var dishes :[Dish] = []
override func viewDidLoad() {
super.viewDidLoad()
// configure the observation
token = self.observe(\.dishes) { object, change in
// change is always nil
print(object)
print(change)
}
updateTableView()
}
Whenever the dishes array is changed, the observation is triggered. But my question is how can I get the actual changes that happened, that is, how can I access the actual Dish object that triggered the change?
KVO, which stands for Key-Value Observing, is one of the techniques for observing the program state changes available in Objective-C and Swift. The concept is simple: when we have an object with some instance variables, KVO allows other objects to establish surveillance on changes for any of those instance variables.
Key-value observing is a mechanism that enables an object to be notified directly when a property of another object changes. It is a mode of communication between objects in applications designed in conformance with the Model-View-Controller design pattern.
KVO and KVC or Key-Value Observing and Key-Value Coding are mechanisms originally built and provided by Objective-C that allows us to locate and interact with the underlying properties of a class that inherits NSObject at runtime.
Key-Value Observing, KVO for short, is an important concept of the Cocoa API. It allows objects to be notified when the state of another object changes.
I think the reason change
is coming up with nil
is because you haven't specified options.
Rewrite as follows:
override func viewDidLoad() {
super.viewDidLoad()
// configure the observation
token = self.observe(\.dishes, options: [.new,.old]) { object, change in
print(object)
let set1 = Set(change.newArray!)
let set2 = Set(change.oldArray!)
let filter = Array(set1.subtract(set2))
print(filter)
}
updateTableView()
}
Note that I have done a bit of guesswork here about your Dish
object. I am assuming you have made it conform to the Equatable
protocol, and this is a necessary step for the solution to work.
UPDATE: This requirement has now been reflected in the official Apple documentation here.
If you don't need to know how a property has changed, omit the options parameter. Omitting the options parameter forgoes storing the new and old property values, which causes the oldValue and newValue properties to be nil.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With