从 NSUserDefault 字典 iOS 中删除所有键

我使用 NSUserDefault 字典来存储基本信息,如高分等,这样当用户关闭应用程序数据不会丢失。无论如何,我使用:

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

例如,如果我想存储一个新的高分,我会这样做:

[prefs setInteger:1023 forKey:@"highScore"];
[prefs synchronize];  //this is needed in case the app is closed.

之后,如果我想重新获得高分,我会这样做:

[prefs integerForKey:@"highScore"];

无论如何,关键是我存储了很多其他的东西,因为 NSUserDefaults enable你存储 booleansintegersobjects等。我必须执行什么方法来删除所有的键,使 NSUserDefault 成为像我第一次启动应用程序?

我在寻找这样的东西:

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs deleteAllKeysAndObjectsInTheDictionary];

或者有一种方法可以得到所有的键,我必须循环遍历每个对象,但我不知道如何删除它们。

编辑:

我试过了:

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[NSUserDefaults resetStandardUserDefaults];
[prefs synchronize];

我仍然能够取得高分。

66100 次浏览

这种方法不是这样做的吗:

+ (void)resetStandardUserDefaults

来自 NSUserDefaults的文档:

ResetStandardUserDefault

同步对共享用户默认对象所做的任何更改 从记忆中释放出来。

+ (void)resetStandardUserDefaults

讨论

标准 UserDefault 的后续调用将创建一个新的共享 标准搜索列表的用户默认对象。

基于这一点,你可以做到:

[NSUserDefaults resetStandardUserDefaults];
[NSUserDefaults standardUserDefaults];

现在应该重新设定违约率。

如果你看一下 NSUserDefault 文档,你会看到一个方法 - (NSDictionary *) dictionaryRepresentation。对标准用户默认值使用此方法,可以获得用户默认值中的所有键的列表。然后您可以使用它来清除用户默认值:

- (void)resetDefaults {
NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
NSDictionary * dict = [defs dictionaryRepresentation];
for (id key in dict) {
[defs removeObjectForKey:key];
}
[defs synchronize];
}

+ (void) resetStandardUserDefaults不会持久化更改,它只是重置内存中的用户默认对象,以便下一个 synchronize调用将从磁盘上的副本中读取,而不是用磁盘上的版本覆盖现有的内存中的值。

对键进行迭代会更好,但是实际上有一个函数可以为您做到这一点: removePersistentDomainForName:

// you can usually get the domain via [[NSBundle mainBundle] bundleIdentifier]
[[NSUserDefaults standardUserDefaults]
removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
// or use a string for any other settings domains you use
//[[NSUserDefaults standardUserDefaults]
// removePersistentDomainForName:@"com.mycompany.myappname"];
[[NSUserDefaults standardUserDefaults] synchronize];

synchronize操作结束时,用户默认值的磁盘和内存副本将不包含应用程序设置的任何值。

最简单的方法就是用同样的结果 ,就像 Alex Nichol 的最佳答案一样:

NSString *appDomain = NSBundle.mainBundle.bundleIdentifier;
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
[[NSUserDefaults standardUserDefaults] synchronize];

一句话:

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:NSBundle.mainBundle.bundleIdentifier];

快速版:

if let bid = NSBundle.mainBundle().bundleIdentifier {
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(bid)
}

斯威夫特笔下的线条:

斯威夫特

NSUserDefaults.standardUserDefaults().removePersistentDomainForName(
NSBundle.mainBundle().bundleIdentifier!)

Swift 4

UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)

简单解决方案

目标丙:

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];

Swift 3.0到 Swift 5.0:

if let appDomain = Bundle.main.bundleIdentifier {
UserDefaults.standard.removePersistentDomain(forName: appDomain)
}

对于斯威夫特3:

let appDomain = Bundle.main.bundleIdentifier!
UserDefaults.standard.removePersistentDomain(forName: appDomain)

对于斯威夫特3:

if let bundle = Bundle.main.bundleIdentifier {
UserDefaults.standard.removePersistentDomain(forName: bundle)
}

对于那些希望在测试目标中执行此操作的人,请使用此方法(因为 removePersistentDomain不适用于此情况)

斯威夫特3:

for key in Array(UserDefaults.standard.dictionaryRepresentation().keys) {
UserDefaults.standard.removeObject(forKey: key)
}

斯威夫特

func resetUserDefaults(){
let userDefaults = NSUserDefaults.standardUserDefaults()
let dict = userDefaults.dictionaryRepresentation() as NSDictionary
        

for key in dict.allKeys {
userDefaults.removeObjectForKey(key as! String)
}
        

userDefaults.synchronize()
}

斯威夫特三号或者四号 我们甚至可以将所描述的片段简化为这个现代表达式:

func clearAll() {
let settingsDictionary = userDefaults.dictionaryRepresentation()
settingsDictionary.forEach { key, _ in userDefaults.removeObject(forKey: key) }
userDefaults.synchronize()
}

斯威夫特
放在你的逻辑中

if let appDomain = Bundle.main.bundleIdentifier {
UserDefaults.standard.removePersistentDomain(forName: appDomain)
}

以 Swift (最新语法)删除所有 UserDefault 值

//remove UserDefaults
if let identifier = Bundle.main.bundleIdentifier {
UserDefaults.standard.removePersistentDomain(forName: identifier)
UserDefaults.standard.synchronize()
}

我发现将代码放在 UserDefaults的扩展中是最方便的。

Swift 5

extension UserDefaults {
static func clear() {
guard let domain = Bundle.main.bundleIdentifier else { return }
UserDefaults.standard.removePersistentDomain(forName: domain)
UserDefaults.standard.synchronize()
}
}

用法

UserDefaults.clear()

在 Swift 5.0下面单行代码就足够了。

UserDefaults.standard.dictionaryRepresentation().keys.forEach(defaults.removeObject(forKey:))

我用这个:

UserDefaults.standard.removeAll()