内容简介:用户默认数据库的接口,您可以在应用程序的启动过程中持久存储键值对。当系统调用
An interface to the user’s defaults database, where you store key-value pairs persistently across launches of your app.
用户默认数据库的接口,您可以在应用程序的启动过程中持久存储键值对。
当系统调用 [[NSUserDefaults standardUserDefaults] setObject:@"" forKey:@""]
后系统会为用户在 沙盒 下的 Libray/Preferences
目录下创建 plist
文件,文件名为当前应用的 Bundle Identifier 即 [[NSBundle mainBundle] bundleIdentifier]
用户可以通过 NSUserDefaults
接口的参数获取到该文件夹下的数据.
1.2 NSUserDefaults
数据读写
1.2.1 目标存储内容
The defaults system allows an app to customize its behavior to match a user’s preferences.
应用通过 NSUserDefaults
存储用户在应用内的 偏好设置 ,比如用户设置了应用的主题颜色,使用 NSUserDefaults
存储后,用户再次进入应用,应用可以读取到该数据后配置应用的主题颜色( NSUserDefaults
保存的数据会缓存起来所以可以实现该类似的需求.但当用户卸载了应用后,数据也将被清除, NSUserDefaults
保存的数据不会通过 iTunes 传递到另外的设备也不会存储到 iCloud 上面).
因为 NSUserDefaults
存储的数据是写入到 plist
文件下,所以用 NSUserDefaults
存储的数据应该是小型数据而不应该是数据量大的数据.
1.2.2 数据写入
The NSUserDefaults class provides convenience methods for accessing common types such as floats, doubles, integers, Boolean values, and URLs. These methods are described in Setting Default Values.
A default object must be a property list—that is, an instance of (or for collections, a combination of instances of) NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. If you want to store any other type of object, you should typically archive it to create an instance of NSData.
因为 NSUserDefaults
存储的数据是写入到 plist
文件的,所以 NSUserDefaults
支持存储的数据有限,包括有 NSData
, NSString
, NSNumber
, NSDate
, NSArray
, NSDictionary
类型的数据.通常我们使用 - (void)setObject:(nullable id)value forKey:(NSString *)defaultName;
来设置我们的值.但有些特殊的数据, 系统也提供了几个便利的设置值方法.
- (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName; - (void)setFloat:(float)value forKey:(NSString *)defaultName; - (void)setDouble:(double)value forKey:(NSString *)defaultName; - (void)setBool:(BOOL)value forKey:(NSString *)defaultName; 复制代码
这里边有一个比较特殊的方法 -setURL:forKey
,你可以保存数据的本地地址而不需要直接保存完整数据.
/// -setURL:forKey is equivalent to -setObject:forKey: except that the value is archived to an NSData. Use -URLForKey: to retrieve values set this way. - (void)setURL:(nullable NSURL *)url forKey:(NSString *)defaultName API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); 复制代码
当你存储的文件可能存在更改的情况下需要用到一下 方法 去建立 书签 存储数据.
/* Returns bookmark data for the URL, created with specified options and resource values. If this method returns nil, the optional error is populated. */ - (nullable NSData *)bookmarkDataWithOptions:(NSURLBookmarkCreationOptions)options includingResourceValuesForKeys:(nullable NSArray<NSURLResourceKey> *)keys relativeToURL:(nullable NSURL *)relativeURL error:(NSError **)error API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); /* Creates and Initializes an NSURL that refers to a location specified by resolving bookmark data. If this method returns nil, the optional error is populated. */ + (nullable instancetype)URLByResolvingBookmarkData:(NSData *)bookmarkData options:(NSURLBookmarkResolutionOptions)options relativeToURL:(nullable NSURL *)relativeURL bookmarkDataIsStale:(BOOL * _Nullable)isStale error:(NSError **)error API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); 复制代码
当我们设置数据后,系统并不会立即保存到本地,而是会在一个系统觉得恰当的时间点进行存储,如果我们需要立即存储的话需要调用 - (BOOL)synchronize;
方法来实现.
1.2.3 数据读取
通常我们调用 - (nullable id)objectForKey:(NSString *)defaultName;
方法来获取我们存储的数据.系统还为我们提供了一些特别的接口供我们使用.
- (nullable NSString *)stringForKey:(NSString *)defaultName; - (nullable NSArray *)arrayForKey:(NSString *)defaultName; - (nullable NSDictionary<NSString *, id> *)dictionaryForKey:(NSString *)defaultName; - (nullable NSData *)dataForKey:(NSString *)defaultName; - (nullable NSArray<NSString *> *)stringArrayForKey:(NSString *)defaultName; - (NSInteger)integerForKey:(NSString *)defaultName; - (float)floatForKey:(NSString *)defaultName; - (double)doubleForKey:(NSString *)defaultName; - (BOOL)boolForKey:(NSString *)defaultName; - (nullable NSURL *)URLForKey:(NSString *)defaultName API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); 复制代码
注意点:当我们存储的数据是 可变类型 时,读取后的数据将变为 不可变类型 .
1.2.4 数据变化监听
当我们的 NSUserDefaults
实例所存储的数据变更时,系统会发送 NSUserDefaultsDidChangeNotification
的通知,通知会返回当前更改的 NSUserDefaults
实例对象回来.所以当需要监听某个 NSUserDefaults
数据存储的数据变化时,可以添加该通知的观察者.
1.3 沙盒的注意事项
我们的应用数据时存储在沙盒目录中的,正常情况下其他应用是无法读取到我们应用的数据.但是有两种情况是被允许应用去读取其他应用的数据.
- App extensions on macOS and iOS
- Other apps in your application group on macOS
当我们有扩展程序或者多个应用在同一个应用组里面的时候就能被允许进行这样的操作.
当我们设置了两个应用为在同一个 App Groups
后,我们的代码便可以通过组名来获取应用间共享的数据了.
[[NSUserDefaults alloc] initWithSuiteName:@"group.NSUserDefaultsDemo"] 复制代码
1.4 线程安全
Thread SafetyThe UserDefaults class is thread-safe.
系统在读写 NSUserDefaults
时是有做 线程安全 措施的,所以开发者在使用 NSUserDefaults
时是不需要考虑 多线程 问题.
2.API介绍
系统提供的默认存储接口
@property (class, readonly, strong) NSUserDefaults *standardUserDefaults; 复制代码
清空当前默认存储的数据,数据如果被 KVO
监听的也将失效.
+ (void)resetStandardUserDefaults; 复制代码
通过域名创建数据表,这里的 suitename
为 nil
时生成的实例将会是系统提供的默认接口,这里不应该用应用的 bundle identifier
和 NSGlobalDomain
来作为参数.传入的 suitename
将作为 identifier
来存储.
- (nullable instancetype)initWithSuiteName:(nullable NSString *)suitename 复制代码
返回当前所有的数据
- (NSDictionary<NSString *, id> *)dictionaryRepresentation; 复制代码
移除当前 key
以及对应的值,这个方法和 -[... setObject:nil forKey:defaultName]
是等价的
- (void)removeObjectForKey:(NSString *)defaultName; 复制代码
添加域名(当添加了另一个域名后,可以该实例查询数据时也将会在此域名下查询,优先在当前域名查询,结束后在其他子域名查询)
- (void)addSuiteNamed:(NSString *)suiteName; 复制代码
移除域名
- (void)removeSuiteNamed:(NSString *)suiteName; 复制代码
注册 字典 数据,常放在 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
调用.当你需要事先存储一些基本数据供应用读取时,就可以通过此方法来配置了.
- 注意的是如果 字典 里包含有了更改过后的
Key
,该Key
将不会再被写入,比如 字典 中有userName
这个Key
,Value
为10001
的默认值,当再应用内更改了userName
的值后,下次再进入应用,该Key
不会再赋值为10001
了.
- (void)registerDefaults:(NSDictionary<NSString *, id> *)registrationDictionary; 复制代码
不稳定域相关接口
/// 不稳定域的不稳定域名数组(包括了NSRegistrationDomain, NSArgumentDomain) @property (readonly, copy) NSArray<NSString *> *volatileDomainNames; /// 获取某个不稳定域名下对应的数据 - (NSDictionary<NSString *, id> *)volatileDomainForName:(NSString *)domainName; /// 通过域名以及字典数据设置不稳定域 - (void)setVolatileDomain:(NSDictionary<NSString *, id> *)domain forName:(NSString *)domainName; /// 通过域名以及不稳定域 - (void)removeVolatileDomainForName:(NSString *)domainName; 复制代码
稳定域相关接口,与不稳定域类似
- (nullable NSDictionary<NSString *, id> *)persistentDomainForName:(NSString *)domainName; - (void)setPersistentDomain:(NSDictionary<NSString *, id> *)domain forName:(NSString *)domainName; - (void)removePersistentDomainForName:(NSString *)domainName; 复制代码
注意点
- 稳定域将会写入本地
Preferences
文件夹里面生成对应的plist
文件,不稳定域将不会生成. -
initWithSuiteName
生成的为稳定域
3.域
在 NSUserDefault
中存在域的概念,包含5个部分 NSArgumentDomain
, Application
, NSGlobalDomain
, Languages
, NSRegistrationDomain
。
-
NSArgumentDomain
:代表的是命令行参数,可以在Edit Scheme->Arguments->Arguments Passed On Launch
中添加,格式是-key value
。 -
Application
: 应用程序域,设置的方法默认数据保存是在这里 -
NSGlobalDomain
: 全局域,所有应用程序都将公用该域 -
Languages
: 国际化语言版本域 -
NSRegistrationDomain
: 临时域,-(void)registerDefaults:(NSDictionary*)registrationDictionary
方法被调用是数据是保存在这里。在读取数据时,都会在底层的存储结构中进行一次搜索,搜索的顺序是这样:
NSArgumentDomain->Application->NSGlobalDomain->Languages->NSRegistrationDomain 复制代码
4.参考
以上所述就是小编给大家介绍的《iOS-NSUserDefaults详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Flutter 完整开发实战详解(十六、详解自定义布局实战)
- 数据结构 1 线性表详解 链表、 栈 、 队列 结合JAVA 详解
- 详解Openstack环境准备
- Java泛型详解
- iOS RunLoop 详解
- Raft协议详解
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Two Scoops of Django
Daniel Greenfeld、Audrey M. Roy / CreateSpace Independent Publishing Platform / 2013-4-16 / USD 29.95
Two Scoops of Django: Best Practices For Django 1.5 is chock-full of material that will help you with your Django projects. We'll introduce you to various tips, tricks, patterns, code snippets, and......一起来看看 《Two Scoops of Django》 这本书的介绍吧!