清除NSUserDefaults


Answers:


514

您可以这样删除应用程序的持久域:

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

在Swift 3及更高版本中:

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

这与@samvermette的答案类似,但更干净一些。


这很好,谢谢!只是不要忘了之后释放appDomain。
IcyBlueRose

15
@IcyBlueRose-bundleIdentifier是一个自动释放的对象,因为它不是以init或new开头的,因此您将过度释放它。
克里斯托弗·罗杰斯

1
很高兴知道,谢谢!但是我在谈论字符串appDomain。该汽车也发布了吗?
IcyBlueRose

2
@IcyBlueRose bundleIdentifier返回的对象与appDomain引用的对象相同。
克里斯托弗·罗杰斯

2
我似乎无法再在10.8上使用它,有人可以确认它是否可以工作吗?这里有一个相关的SO问题:stackoverflow.com/questions/13595415/...
DaGaMs

102

此代码将默认值重置为注册域:

[[NSUserDefaults standardUserDefaults] setPersistentDomain:[NSDictionary dictionary] forName:[[NSBundle mainBundle] bundleIdentifier]];

换句话说,它 removeObjectForKey针对您在该应用中注册的每个按键。

在此Apple开发者论坛主题上的贡献归功于Ken Thomases


4
谢谢你 为什么[NSUserDefaults resetStandardUserDefaults]不这样做超出我的范围。
jakeboxer 2011年

2
@jboxer我刚刚花了一些时间研究Apple文档,并且resetStandardUserDefaults基本上将内存中的缓冲区刷新到磁盘上并将其擦除。因此,下次您尝试检索一个值时,它必须从磁盘上获取它。核心数据的NSManagedObjectContext也使用类似的“重置”术语。
Christopher Rogers

2
糟糕,我的意思是说它擦除了内存中的缓冲区而不将其写入磁盘。因此,您在同步到磁盘之前所做的任何更改都将丢失。
Christopher Rogers

4
克里斯托弗,我想你可能会倒退,尽管情况可能有所改变。resetStandardUserDefaults是我迄今为止在iOS中看到的最混乱的名称的调用。Apple Docs说:“同步对共享用户默认对象的所有更改,并将其从内存中释放出来。” 因此它实际上应该称为flushAndReleaseStandardUserDefaults。我花时间对一个旧评论发表评论,因为我只是被这个电话吸引住了,并希望避免其他人被烧死(我现在必须告诉客户端我需要更新90个应用程序)。
安迪·邓特

97

您是否尝试过使用-removeObjectForKey吗?

 [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"defunctPreference"];

欢呼声。非常感激。
TonyNeallon

5
有什么方法可以删除所有现有键的对象?
samvermette 2010年

2
虽然我知道这似乎可行,但为什么defunctPreference不是某种系统定义的常量?我肯定会在将来的某一天停止工作。
David H

之后是否需要同步?
特拉维斯M.15年

30

这是Swift中的答案:

let appDomain = NSBundle.mainBundle().bundleIdentifier!
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(appDomain)

8
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!)单线

3
或更安全:if let domainName = NSBundle.mainBundle().bundleIdentifier { NSUserDefaults.standardUserDefaults().removePersistentDomainForName(domainName) }
Valentin Shergin '16

1
Grace的oneliner的Swift 4版本:UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
卡斯滕·哈格曼

28

如果在开发时需要它,还可以重置模拟器,删除所有NSUserDefaults

iOS模拟器->重置内容和设置...

请记住,它还将删除模拟器上的所有应用程序和文件。


15
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
for (NSString *key in [defaultsDictionary allKeys]) {
                    [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
}

7

在Swift中:

let defaults = NSUserDefaults.standardUserDefaults()
defaults.dictionaryRepresentation().keys.forEach { defaults.removeObjectForKey($0) }

6

注意:此答案也已针对Swift进行了更新。

将其放在一行上该怎么办?

扩展@Christopher Rogers的答案–已被接受。

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

是的,有时候您可能需synchronize要这样做,

[[NSUserDefaults standardUserDefaults] synchronize];

我已经创建了一种方法来做到这一点,

- (void) clearDefaults {
    [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

迅速

迅速,甚至更容易。

extension UserDefaults {
    class func clean() {
        guard let aValidIdentifier = Bundle.main.bundleIdentifier else { return }
        standard.removePersistentDomain(forName: aValidIdentifier)
        standard.synchronize()
    }
}

和用法

UserDefaults.clean()

6

我喜欢扩展使代码更简洁的扩展:

extension NSUserDefaults {
    func clear() {
        guard let domainName = NSBundle.mainBundle().bundleIdentifier else {
            return
        }

        self.removePersistentDomainForName(domainName)
    }
}

斯威夫特5

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


2

以上所有答案都非常相关,但是如果仍然无法为已删除的应用重置用户默认设置,则可以重置模拟器的内容设置,它将可以使用。在此处输入图片说明


2

这是一个错误或其他问题,但是removePersistentDomainForName在清除所有NSUserDefaults值时不起作用。

因此,更好的选择是重置PersistentDomain,您可以通过以下方式进行操作:

NSUserDefaults.standardUserDefaults().setPersistentDomain(["":""], forName: NSBundle.mainBundle().bundleIdentifier!)

1

扩展@folse的答案...我相信会有一个更正确的实现方式...

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] persistentDomainForName: appDomain];
    for (NSString *key in [defaultsDictionary allKeys]) {
      NSLog(@"removing user pref for %@", key);
      [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
    }

...正在调用NSUserDefault的persistentDomainForName:方法。docs指出,方法“返回包含指定持久域中的键和值的字典”。调用dictionaryRepresentation:将会返回一个字典,该字典可能会包含其他设置,因为它适用于更广泛的范围。

如果您需要过滤掉任何将要重置的值,那么遍历键就是这样做的方法。显然,如果您只想无视应用程序的所有偏好,那么上面发布的其他方法之一就是最有效的。



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.