【发布时间】:2010-10-07 09:39:32
【问题描述】:
我使用+[NSUserDefaults standardUserDefaults] 来存储应用程序设置。这由大约十几个字符串值组成。是否可以永久删除这些值而不仅仅是将它们设置为默认值?
【问题讨论】:
标签: ios objective-c cocoa-touch nsuserdefaults
我使用+[NSUserDefaults standardUserDefaults] 来存储应用程序设置。这由大约十几个字符串值组成。是否可以永久删除这些值而不仅仅是将它们设置为默认值?
【问题讨论】:
标签: ios objective-c cocoa-touch nsuserdefaults
您可以像这样删除应用程序的持久域:
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
在 Swift 3 及更高版本中:
if let bundleID = Bundle.main.bundleIdentifier {
UserDefaults.standard.removePersistentDomain(forName: bundleID)
}
这与@samvermette 的回答类似,但在 IMO 上更简洁一些。
【讨论】:
此代码将默认值重置为注册域:
[[NSUserDefaults standardUserDefaults] setPersistentDomain:[NSDictionary dictionary] forName:[[NSBundle mainBundle] bundleIdentifier]];
换句话说,removeObjectForKey 对应于您在该应用中注册的每一个键。
感谢 Ken Thomases 在此 Apple 开发者论坛 thread.
【讨论】:
[NSUserDefaults resetStandardUserDefaults] 不这样做超出了我的理解。
您是否尝试过使用 -removeObjectForKey?
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"defunctPreference"];
【讨论】:
这是 Swift 中的答案:
let appDomain = NSBundle.mainBundle().bundleIdentifier!
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(appDomain)
【讨论】:
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!) one-liner
if let domainName = NSBundle.mainBundle().bundleIdentifier { NSUserDefaults.standardUserDefaults().removePersistentDomainForName(domainName) }
UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
如果你在开发过程中需要它,你也可以重置你的模拟器,删除所有NSUserDefaults。
iOS 模拟器 -> 重置内容和设置...
请记住,它还会删除模拟器上的所有应用程序和文件。
【讨论】:
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
for (NSString *key in [defaultsDictionary allKeys]) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
}
【讨论】:
在斯威夫特中:
let defaults = NSUserDefaults.standardUserDefaults()
defaults.dictionaryRepresentation().keys.forEach { defaults.removeObjectForKey($0) }
【讨论】:
我喜欢让代码更简洁的扩展:
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()
}
}
【讨论】:
注意:此答案也已针对 Swift 进行了更新。
将它放在一条线上怎么样?
扩展@Christopher Rogers 的答案——已被接受。
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
是的,有时你可能需要synchronize它,
[[NSUserDefaults standardUserDefaults] synchronize];
我已经创建了一个方法来做到这一点,
- (void) clearDefaults {
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
[[NSUserDefaults standardUserDefaults] synchronize];
}
斯威夫特?
使用 swift 更容易。
extension UserDefaults {
class func clean() {
guard let aValidIdentifier = Bundle.main.bundleIdentifier else { return }
standard.removePersistentDomain(forName: aValidIdentifier)
standard.synchronize()
}
}
及用法:
UserDefaults.clean()
【讨论】:
我发现了这个:
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 "{}"
来源:https://gist.github.com/ZevEisenberg/5a172662cb576872d1ab
【讨论】:
以上所有答案都非常相关,但如果有人仍然无法重置已删除应用的用户默认设置,那么您可以重置模拟器的内容设置,它会起作用。
【讨论】:
这是一个错误或其他问题,但 removePersistentDomainForName 在清除所有 NSUserDefaults 值时不起作用。
因此,更好的选择是重置PersistentDomain,您可以通过以下方式进行:
NSUserDefaults.standardUserDefaults().setPersistentDomain(["":""], forName: NSBundle.mainBundle().bundleIdentifier!)
【讨论】:
扩展@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: 方法。正如文档所述,该方法“返回包含指定持久域中的键和值的字典”。相反,调用 dictionaryRepresentation: 将返回一个字典,该字典可能包含其他设置,因为它适用于更广泛的范围。
如果您需要过滤掉任何要重置的值,那么遍历键是一种方法。显然,如果您只想删除应用程序的所有首选项而不考虑,那么上面发布的其他方法之一是最有效的。
【讨论】:
如果需要重置的应用程序设置是用于访问麦克风的 nsuserdefault(我的情况),一个简单的解决方案是来自 Anthony McCormick (Iphone - How to enable application access to media on the device? - ALAssetsLibraryErrorDomain Code=-3312 "Global denied access") 的回答。
在设备上,转到设置>常规>重置>重置位置警告
【讨论】:
试试这个,它对我有用。
单行代码
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
【讨论】: