清除NSUserDefaults

Ton*_*lon 282 cocoa-touch objective-c nsuserdefaults ios

我正在+[NSUserDefaults standardUserDefaults]用来存储应用程序设置.这包含大约十几个字符串值.是否可以永久删除这些值而不是仅将它们设置为默认值?

Chr*_*ers 509

您可以删除应用程序的持久域,如下所示:

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
Run Code Online (Sandbox Code Playgroud)

在Swift 3及更高版本中:

if let bundleID = Bundle.main.bundleIdentifier {
    UserDefaults.standard.removePersistentDomain(forName: bundleID)
}
Run Code Online (Sandbox Code Playgroud)

这类似于@samvermette的答案,但IMO有点清洁.

  • @IcyBlueRose - bundleIdentifier是一个自动释放的对象,因为它不是以init或new开头的,所以你会过度释放它. (15认同)
  • @IcyBlueRose bundleIdentifier返回的对象与appDomain引用的对象相同. (2认同)
  • 我似乎无法让这个在10.8上工作,有人可以确认这是有效的吗?这是一个相关的SO问题:http://stackoverflow.com/questions/13595415/osx-preferences-file-removepersistentdomainforname-has-different-functionality (2认同)

sam*_*tte 102

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

[[NSUserDefaults standardUserDefaults] setPersistentDomain:[NSDictionary dictionary] forName:[[NSBundle mainBundle] bundleIdentifier]];
Run Code Online (Sandbox Code Playgroud)

换句话说,它removeObjectForKey适用于您在该应用中注册的每一个键.

在此Apple开发者论坛主题上向Ken Thomases致信.

  • 谢谢一堆.为什么`[NSUserDefaults resetStandardUserDefaults]`不这样做是超出我的. (4认同)
  • 克里斯托弗,我认为你可能会倒退,尽管事情可能会发生变化.resetStandardUserDefaults是迄今为止我在iOS中看到的最容易混淆的调用.Apple Docs说"同步对共享用户默认对象所做的任何更改,并将其从内存中释放出来." 所以它应该被称为flushAndReleaseStandardUserDefaults.我正在花时间评论旧的评论,因为我刚接到这个电话,并希望避免其他人被烧毁(我现在必须告诉客户我需要更新90个应用程序). (3认同)
  • @jboxer我只是花了一些时间研究Apple文档和resetStandardUserDefaults基本上将内存缓冲区刷新到磁盘并擦除它干净.因此,下次尝试检索值时,必须从磁盘中获取它.Core Data的NSManagedObjectContext也使用类似的"重置"术语. (2认同)
  • 糟糕,我的意思是它擦除内存缓冲区而不将其写入磁盘.因此,在同步到磁盘之前所做的任何更改都将丢失. (2认同)

sbo*_*oth 96

你尝试过使用removeObjectForKey吗?

 [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"defunctPreference"];
Run Code Online (Sandbox Code Playgroud)

  • 有没有办法删除所有现有密钥的对象? (5认同)
  • 虽然我理解这似乎有效,但为什么defunctPreference不是某种系统定义的常量?我肯定会感到紧张,将来有一天会停止工作. (2认同)

jul*_*aad 30

这是Swift的答案:

let appDomain = NSBundle.mainBundle().bundleIdentifier!
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(appDomain)
Run Code Online (Sandbox Code Playgroud)

  • `NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!)` 单行 (8认同)
  • 或者更安全:`if let domainName = NSBundle.mainBundle().bundleIdentifier {NSUserDefaults.standardUserDefaults().removePersistentDomainForName(domainName)}` (3认同)

Rog*_*oli 28

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

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

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


fol*_*lse 14

NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
for (NSString *key in [defaultsDictionary allKeys]) {
                    [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
}
Run Code Online (Sandbox Code Playgroud)


Ada*_*ite 7

在Swift中:

let defaults = NSUserDefaults.standardUserDefaults()
defaults.dictionaryRepresentation().keys.forEach { defaults.removeObjectForKey($0) }
Run Code Online (Sandbox Code Playgroud)


Dan*_*ico 5

我找到了这个:

osascript -e 'tell application "iOS Simulator" to quit'
xcrun simctl list devices | grep -v '^[-=]' | cut -d "(" -f2 | cut -d ")" -f1 | xargs -I {} xcrun simctl erase "{}"
Run Code Online (Sandbox Code Playgroud)

资料来源:https://gist.github.com/ZevEisenberg/5a172662cb576872d1ab


Hem*_*ang 5

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

怎么把它放在一条线上?

延伸@Christopher Rogers的答案 - 接受的答案.

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
Run Code Online (Sandbox Code Playgroud)

是的,有时你可能需要synchronize它,

[[NSUserDefaults standardUserDefaults] synchronize];
Run Code Online (Sandbox Code Playgroud)

我创建了一个方法来做到这一点,

- (void) clearDefaults {
    [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
    [[NSUserDefaults standardUserDefaults] synchronize];
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特

随着迅捷,它变得更加容易.

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

用法:

UserDefaults.clean()
Run Code Online (Sandbox Code Playgroud)


Val*_*gin 5

当他们使代码更清洁时,我喜欢扩展:

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

        self.removePersistentDomainForName(domainName)
    }
}
Run Code Online (Sandbox Code Playgroud)