iOS-NSUserDefaults详解

栏目: IOS · 发布时间: 5年前

内容简介:用户默认数据库的接口,您可以在应用程序的启动过程中持久存储键值对。当系统调用

NSUserDefaults

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 接口的参数获取到该文件夹下的数据.

iOS-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 后,我们的代码便可以通过组名来获取应用间共享的数据了.

iOS-NSUserDefaults详解
[[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;
复制代码

通过域名创建数据表,这里的 suitenamenil 时生成的实例将会是系统提供的默认接口,这里不应该用应用的 bundle identifierNSGlobalDomain 来作为参数.传入的 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 , Value10001 的默认值,当再应用内更改了 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个部分 NSArgumentDomainApplicationNSGlobalDomainLanguagesNSRegistrationDomain

  • NSArgumentDomain :代表的是命令行参数,可以在 Edit Scheme->Arguments->Arguments Passed On Launch 中添加,格式是 -key value
  • Application : 应用程序域,设置的方法默认数据保存是在这里
  • NSGlobalDomain : 全局域,所有应用程序都将公用该域
  • Languages : 国际化语言版本域
  • NSRegistrationDomain : 临时域,- (void)registerDefaults:(NSDictionary*)registrationDictionary 方法被调用是数据是保存在这里。在读取数据时,都会在底层的存储结构中进行一次搜索,搜索的顺序是这样:
NSArgumentDomain->Application->NSGlobalDomain->Languages->NSRegistrationDomain
复制代码

4.参考

谈谈大家熟悉的NSUserDefault

iOS笔记之NSUserDefaults

iOS通过NSUserDefaults实现简单的应用间数据传递


以上所述就是小编给大家介绍的《iOS-NSUserDefaults详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Two Scoops of Django

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》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具