Last active
August 28, 2016 21:04
-
-
Save loganmoseley/02ea76f580dd8c5e2a16f1ef6da91bfe to your computer and use it in GitHub Desktop.
Tests the interaction of KVO and resetStandardUserDefaults().
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
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