Reputation: 9660
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?
Upvotes: 5
Views: 3044
Reputation: 9925
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.
Upvotes: 6