我在应用程序启动时通过[NSUserDefaults registerDefaults:]
调用注册了一堆偏好值。但是在某个阶段,我需要用新的偏好值替换它们,但新值的范围(键集)比初始值小。因此,在再次调用[NSUserDefaults registerDefaults:]
后,我会得到一些未被替换的旧值和一些新值。有没有可能删除先前注册的值?
我在应用程序启动时通过[NSUserDefaults registerDefaults:]
调用注册了一堆偏好值。但是在某个阶段,我需要用新的偏好值替换它们,但新值的范围(键集)比初始值小。因此,在再次调用[NSUserDefaults registerDefaults:]
后,我会得到一些未被替换的旧值和一些新值。有没有可能删除先前注册的值?
如果要完全替换已注册的默认值,您需要替换NSRegistrationDomain
域(顺便说一下,该域是易变的)。
如果要删除单个已注册的默认值,您需要获取NSRegistrationDomain
中的值,删除有问题的键,并替换该域。
NSUserDefaults
的类别可能如下所示:
@implementation NSUserDefaults (UnRegisterDefaults)
- (void)unregisterDefaultForKey:(NSString *)defaultName {
NSDictionary *registeredDefaults = [[NSUserDefaults standardUserDefaults] volatileDomainForName:NSRegistrationDomain];
if ([registeredDefaults objectForKey:defaultName] != nil) {
NSMutableDictionary *mutableCopy = [NSMutableDictionary dictionaryWithDictionary:registeredDefaults];
[mutableCopy removeObjectForKey:defaultName];
[self replaceRegisteredDefaults:[mutableCopy copy]];
}
}
- (void)replaceRegisteredDefaults:(NSDictionary *)dictionary {
[[NSUserDefaults standardUserDefaults] setVolatileDomain:dictionary forName:NSRegistrationDomain];
}
@end
动机:
我需要这个的原因是因为我想要开启用户代理欺骗(出于第三方兼容性的原因)。用户代理欺骗似乎只在通过 registerDefaults:
设置值时才有效,所以使用 set...:forKey:
无法停止用户代理字符串。如果我想在稍后的某个时间停止欺骗用户代理(而无需重新启动应用程序),我需要一种方法来移除默认值。此外,我不想清除我的应用程序用户注册的其他默认值。上述解决方案似乎完美地解决了这个问题。
以下是EthanB原回答的Swift 3版本:
extension UserDefaults {
/// Unregisters a value set in the UserDefaults.registrationDomain, if it exists
func unregister(defaultsFor key: String) {
var registeredDefaults = volatileDomain(forName: UserDefaults.registrationDomain)
registeredDefaults[key] = nil
setVolatileDomain(registeredDefaults, forName: UserDefaults.registrationDomain)
}
}
在我的UIWebView
的deinit
中使用,将默认用户代理恢复回我的应用程序。
removeVolatileDomainForName:
方法删除NSRegistrationDomain
。这将清除通过registerDefaults:
方法注册的所有值。但是,如果您需要这样做,那么您很可能正在做一些错误的事情。正确的方式是使用其中一种set...:forKey:
方法实际存储新设置。