NSUserDefaults值得关注的地方
以前对NSUserDefaults的理解很浅显,只是用于存储一些应用内的某些简单的键值对或者存储用户的一些设置。比如记录当前应用内是否开启定位、是否自动登录、记录某个事件的状态、或者NStimer倒计时时间等简单键值对。看了一些博客以及亲自实践后发现一些可能忽略的问题。
1.线程是否安全:
Interprocess: Preferences may be accessible to and modified from multiple processes simultaneously (for example between an application and an extension).
苹果官方文档中明确指出这个类是线程安全的
2.可用于键值的对象
存取时用到的对象不再是实现了NSCopying协议的任意对象就可以作为键值,而只能用NSString作为键值来存取对象。
3.如何删除全部键值对
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//方法一
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:bundleIdentifier];
//方法二
NSDictionary *dict = [userDefaults dictionaryRepresentation];
for (NSString *key in dict) {
[userDefaults removeObjectForKey:key];
}
[userDefaults synchronize];
这里需要注意的是[userDefaults dictionaryRepresentation]获取的不仅仅是应用的 BundleIdentifier所对应的domain下的key-value,还包含NSArgumentDomain、NSGlobalDomain、NSRegistrationDomain等domain下的key-value,但是删除的仅仅是BundleIdentifier对应domian下的key-value
4.可变性及其效率参看参考资料
对NSUserDefaults对象发valueForKey:消息,返回的数据是不可变的,尽管setValue:forKey:时传入的可能是可变的数据对象
5.可以存储哪些对象
仅支持NSString, NSData, NSNumber, NSDate, NSArray, and NSDictionary这几种对象,而集合对象中也只能包含这几种对象。
如果存入自定义对象会报类似下面的错误
Attempt to set a non-property-list object <NSObject: 0x608000010d40> as an NSUserDefaults/CFPreferences value for key objc
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object <NSObject: 0x608000010d40> for key objc'