详解 NSUserDefaults
每次读取把所有内容吞进内存,直接在内存操作,再一次性覆盖文件,不适合存大量数据,就是plist保存到本地的,它自己会隔一段时间保存到本地,为保证时效,自己调用 synchronize
registerDefaults
当使用 NSUserDefaults 读取值时,当它没有设定时走默认值。
设置的默认值是不是持久化存储的,每次启动App的时候都要设置一次。
Domain
当我们调用 [NSUserDefaults standardUserDefaults]
方法时,它就会初始化,并且它默认会包含5个Domain,分别:
- NSArgumentDomain 命令行参数,可以在Xcode中设置
- Application App中存取的值
- NSGlobalDomain
- Languages 语言的相关信息
- NSRegistrationDomain 注册默认值
在 NSUserDefaults 中我们可以看到 NSArgumentDomain、NSGlobalDomain、NSRegistrationDomain三个域。
- (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName;
/// -setFloat:forKey: is equivalent to -setObject:forKey: except that the value is converted from a float to an NSNumber.
- (void)setFloat:(float)value forKey:(NSString *)defaultName;
/// -setDouble:forKey: is equivalent to -setObject:forKey: except that the value is converted from a double to an NSNumber.
- (void)setDouble:(double)value forKey:(NSString *)defaultName;
调用set方法都是存储在Application这个域中的。
查看 GNU 的 NSUserDefaults 方法实现:
/*
* Set up search list (excluding language list, which we don't know yet)
*/
[defs->_searchList addObject: GSPrimaryDomain];
[defs->_searchList addObject: NSArgumentDomain];
[defs->_searchList addObject: processName];
[defs persistentDomainForName: processName];
[defs->_searchList addObject: NSGlobalDomain];
[defs persistentDomainForName: NSGlobalDomain];
[defs->_searchList addObject: GSConfigDomain];
[defs->_searchList addObject: NSRegistrationDomain];
/* Load persistent data into the new instance.
*/
[defs synchronize];
/*
* Look up user languages list and insert language specific domains
* into search list before NSRegistrationDomain
*/
uL = [defs stringArrayForKey: @"NSLanguages"];
//注释
* <deflist>
* <term><code>GSPrimaryDomain</code> ... volatile</term>
* <desc>
* Contains values set at runtime and intended to supercede any values
* set in other domains. This should be used with great care since it
* overrides values which may have been set explicitly by the user.
* </desc>
* <term><code>NSArgumentDomain</code> ... volatile</term>
* <desc>
* Contains defaults read from the arguments provided
* to the application at startup.<br />
* Pairs of arguments are used for this, with the first argument in
* each pair being the name of a default (with a hyphen prepended)
* and the second argument of the pair being the value of the default.<br />
* NB. In GNUstep special arguments of the form <code>--GNU-Debug=...</code>
* are used to enable debugging. Despite beginning with a hyphen, these
* are not treated as default keys.
* </desc>
* <term>Application (name of the current process) ... persistent</term>
* <desc>
* Contains application specific defaults, such as window positions.
* This is the domain used by the -setObject:forKey: method and is
* the domain normally used when setting preferences for an application.
* </desc>
* <term><code>NSGlobalDomain</code> ... persistent</term>
* <desc>
* Global defaults applicable to all applications.
* </desc>
* <term>Language (name based on users's language) ... volatile</term>
* <desc>
* Constants that help with localization to the users's
* language.
* </desc>
* <term><code>GSConfigDomain</code> ... volatile</term>
* <desc>
* Information retrieved from the GNUstep configuration system.
* Usually the system wide and user specific GNUstep.conf files,
* or from information compiled in when the base library was
* built.<br />
* In addition to this standard configuration information, this
* domain contains all values from property lists store in the
* GlobalDefaults subdirectory or from the GlobalDefaults.plist file
* stored in the same directory as the system wide GNUstep.conf
* file.
* </desc>
* <term><code>NSRegistrationDomain</code> ... volatile</term>
* <desc>
* Temporary defaults set up by the application.
* </desc>
* </deflist>
发现读取数据时,会在底层的数据结构进行一次搜索,它的顺序是这样:
NSArgumentDomain -> Application -> NSGlobalDomain -> Languages -> NSRegistrationDomain
应用
根据以上加载顺序,我们就可以实现语言不跟系统同步的功能,这就是 NSUserDefaults 分层设计的好处。
在命令行参数中做手脚。微信的语言不跟随系统同步是不是也是这个思路呢,待落实。
Edit Scheme -> Arguments Passed On Launch 选项卡中添加命令行参数。格式如下:
For the purposes of debugging an app target, launch arguments and environment variables can be thought to be equivalent—both change the runtime behavior by defining certain values. In practice, the main difference between the two is that launch arguments begin with a dash (-) and don’t have a separate field for argument values.
栗子:-zll hao
在应用中我们可通过 [[NSUserDefaults standardUserDefaults] volatileDomainForName:NSArgumentDomain];
获取设置的命令行参数
也可以通过 [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]
获取 NSUserDefaults 所有数据
相关链接
NSUserDefaults - 熟悉与陌生
Launch Arguments & Environment Variables
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论