Skip to content

Instantly share code, notes, and snippets.

@loganmoseley
Last active August 28, 2016 21:04
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 loganmoseley/02ea76f580dd8c5e2a16f1ef6da91bfe to your computer and use it in GitHub Desktop.
Save loganmoseley/02ea76f580dd8c5e2a16f1ef6da91bfe to your computer and use it in GitHub Desktop.
Tests the interaction of KVO and resetStandardUserDefaults().
/**
Key-Value Observing of NSUserDefaults.standardUserDefaults is unsafe.
Do not KVO the standardUserDefaults because an invocation of resetStandardUserDefaults()
anywhere in the codebase causes that KVO to silently stop observing. The comment of
resetStandardUserDefaults() in NSUserDefaults.h (below) states this behavior, but I'd
have found the comment more clear had it pointed out that the behavior makes
standardUserDefaults unfit for Key-Value Observation.
> The only visible effect this has is that all KVO observers of the previous
> standardUserDefaults will no longer be observing it.
*/
import Foundation
let key = "key"
class Observer: NSObject {
override init() {
super.init()
NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: key, options: [.New, .Old], context: nil)
}
deinit {
NSUserDefaults.standardUserDefaults().removeObserver(self, forKeyPath: key, context: nil)
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
print("\(keyPath!) value did change: \(change!)")
}
}
// Begin observing standardUserDefaults.
let observer = Observer()
// Confirm that `observer` is notified of changes in standardUserDefaults.
NSUserDefaults.standardUserDefaults().setObject("before resetStandardUserDefaults()", forKey: key)
// Cache pointers and reset standardUserDefaults.
let defaultsBefore = NSUserDefaults.standardUserDefaults()
NSUserDefaults.resetStandardUserDefaults()
let defaultsAfter = NSUserDefaults.standardUserDefaults()
// The pointers taken before and after differ.
print("Did NSUserDefaults.resetStandardUserDefaults(). Before and after objects equal: \(defaultsBefore == defaultsAfter).")
// Confirm that `observer` is NOT notified of changes in the new standardUserDefaults.
NSUserDefaults.standardUserDefaults().setObject("after resetStandardUserDefaults()", forKey: key)
// Clean up for next run.
defaultsBefore.removeObjectForKey(key)
defaultsAfter.removeObjectForKey(key)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment