Skip to content

Instantly share code, notes, and snippets.

@salexkidd
Last active May 14, 2020 05:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save salexkidd/eab683f34a536cf16cfd209625995ba5 to your computer and use it in GitHub Desktop.
Save salexkidd/eab683f34a536cf16cfd209625995ba5 to your computer and use it in GitHub Desktop.
UserDefaults.standard.addObserver calling observeValueForKeyPath multiple times
import Cocoa
let testKey: String = "TESTKEY"
let defaults: UserDefaults = UserDefaults.standard
// Remove Perferences & register default
defaults.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
defaults.register(defaults: [testKey : false])
class testClass: NSObject {
var callCount: Int = 0
override init() {
super.init()
defaults.addObserver(self, forKeyPath: testKey, options: .new, context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
self.callCount += 1
print("Hello World: (\(self.callCount)times)")
}
}
let testObj = testClass()
defaults.set(true, forKey: testKey)
@salexkidd
Copy link
Author

salexkidd commented Jan 24, 2018

code executed by Swift Playground.

Result:

Hello World: (1times)
Hello World: (2times)

Why observeValue call twice??

macOS: High Serra 10.13.2(17C205)
Xcode: Version 9.2 (9C40b)

@comiclandapp
Copy link

Seems to work ok now in Xcode Version 11.4 beta 3 (11N132i).

import UIKit

let testKey: String = "TESTKEY"
let ud: UserDefaults = UserDefaults.standard

// remove preferences & register default
ud.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
ud.register(defaults: [testKey : false])

class testClass: NSObject {

    var callCount: Int = 0

    override init() {
        super.init()

        ud.addObserver(self,
                       forKeyPath: testKey,
                       options: .new,
                       context: nil)
    }
    
    override func observeValue(forKeyPath keyPath: String?,
                               of object: Any?,
                               change: [NSKeyValueChangeKey : Any]?,
                               context: UnsafeMutableRawPointer?) {
        self.callCount += 1
        print("Hello World: (\(self.callCount) times)")
    }
}

let testObj = testClass()
ud.set(true, forKey: testKey)
Hello World: (1 times)

@salexkidd
Copy link
Author

Thx for Replying!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment