如何删除之前通过[NSUserDefaults registerDefaults:]调用注册的值?

7

我在应用程序启动时通过[NSUserDefaults registerDefaults:]调用注册了一堆偏好值。但是在某个阶段,我需要用新的偏好值替换它们,但新值的范围(键集)比初始值小。因此,在再次调用[NSUserDefaults registerDefaults:]后,我会得到一些未被替换的旧值和一些新值。有没有可能删除先前注册的值?


如果您正在开发iOS应用程序,文档(http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html)中提到:“注册域的内容不会写入磁盘;您需要在每次启动应用程序时调用此方法。您可以将plist文件放置在应用程序的资源目录中,并使用从该文件中读取的内容调用registerDefaults:方法。”因此,我认为如果您省略它们,它们将保持为空。您有任何想法为什么旧值会留在默认设置中吗? - Nick
3个回答

13

如果要完全替换已注册的默认值,您需要替换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: 无法停止用户代理字符串。如果我想在稍后的某个时间停止欺骗用户代理(而无需重新启动应用程序),我需要一种方法来移除默认值。此外,我不想清除我的应用程序用户注册的其他默认值。上述解决方案似乎完美地解决了这个问题。


巧合的是遇到了完全相同的问题。谢谢! - jklp
很棒的东西。你应该把它放在GitHub上。谢谢! - Dennis

2

以下是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)
    }
}

在我的UIWebViewdeinit中使用,将默认用户代理恢复回我的应用程序。


0
您可以使用removeVolatileDomainForName:方法删除NSRegistrationDomain。这将清除通过registerDefaults:方法注册的所有值。但是,如果您需要这样做,那么您很可能正在做一些错误的事情。正确的方式是使用其中一种set...:forKey:方法实际存储新设置。

这个解决方案无法解决我的问题,因为removeVolatileDomainForName在比默认级别高1级的阶段起作用。 - macwasik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接