Mac开发中NSUserDefaults用法解析
本文主要介绍在Mac开发过程中, 我们使用NSUserDefaults的场景, 对NSUserDefaults几种比较典型的使用形式进行对比解析, 希望对NSUserDefaults具体用法不是很清楚的读者有帮助.
前言
在iOS 8之后引入了App Group的概念, 我们在其中存储共享的数据, 当然NSUserDefaults也可以存储在其中, 然后实现数据共享, 本文主要对比了在App Group中的NSUserDefaults和我们普通的NSUserDefaults的使用的对比, 基于此我自己写了一个demo, 对两种不同的方式进行了对比, github地址: https://github.com/sjaiwl/MyDemoCode/tree/master/NSUserDefaultesObserverDemo, 建议大家可以先下载代码看一下, 这个demo是基于OS X实现的, 主要是便于查看Group Containers文件夹.
实现方式区别
- App Group中的NSUserDefaults:
其实,实现方式很简单, 就是我们现需要设置App Group, 然后使用App Group Name去初始化,这里有个细节需要注意,就是APP_GROUP_NAME不能和boundle id一样, 否则会出现问题.
_groupDefaultes = [[NSUserDefaults alloc] initWithSuiteName:APP_GROUP_NAME];
2.StandardUserDefaults
这里是我们很熟悉的普通的实现方式
_sharedDefaultes = [NSUserDefaults standardUserDefaults];
两者在实现方式就是不一样的, mac电脑上APP Group中的文件存储位置在:
/users/yourName/Library/Group Containers/ , 可以查看自己的app groups文件夹.
NSUserDefaultsDidChangeNotification监听
但我们需要监听NSUserDefaultes的改变时, 我们可以使用全局的notification来监听, 即:
//notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(defaultsDidChangeNotification:) name:NSUserDefaultsDidChangeNotification object:nil];
当然这是一种比较全局的监听方式, 无论是App Group中的NSUserDefaults还是StandardUserDefaults都是可以监听到的, 当然这种通知方式携带的信息量是很少的, 而且我们无法具体监听某个值得改变.
NSUserDefaultsController
NSUserDefaultsController其实就是用来管理相应的NSUserDefaults的, 当然我们也可以通过NSUserDefaultsController来实现监听, 两种方式下的NSUserDefaultsController的实现形式是不一样的, iOS中没有NSUserDefaultsController, 这个只能基于OS X实现.
App Group
- (NSUserDefaultsController *)groupDefaultesController{
if (!_groupDefaultesController) {
_groupDefaultesController = [[NSUserDefaultsController alloc] initWithDefaults:self.groupDefaultes initialValues:nil];
}
return _groupDefaultesController;
}
StandardUserDefaults
- (NSUserDefaultsController *)sharedDefaultesController{
if (!_sharedDefaultesController) {
_sharedDefaultesController = [NSUserDefaultsController sharedUserDefaultsController];
}
return _sharedDefaultesController;
}
不同的NSUserDefaults必须使用不同的NSUserDefaultsController来处理, 对于监听具体值的变化, 我们很容易想到的一种实现方式, 就是KVO, 下面就是基于KVO实现的:
//add observer
[self.groupDefaultesController addObserver:self
forKeyPath:[@"values." stringByAppendingString:GROUP_VALUE_KEY_STRING]
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
[self.sharedDefaultesController addObserver:self
forKeyPath:[@"values." stringByAppendingString:SHARED_VALUE_KEY_STRING]
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
//observer
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if (object == self.groupDefaultesController && [keyPath isEqualToString:[@"values." stringByAppendingString:GROUP_VALUE_KEY_STRING]]) {
NSLog(@"group defaultes changed");
return;
}
if (object == self.sharedDefaultesController && [keyPath isEqualToString:[@"values." stringByAppendingString:SHARED_VALUE_KEY_STRING]]) {
NSLog(@"shared defaultes changed");
return;
}
}
当然, 不通过NSUserDefaultsController实现, 直接监听NSUserDefaultes可不可以实现呢?
答案是: 在OS X上是可以, 但是iOS 7之后NSUserDefaultes好像不支持KVO了, 而且也没有NSUserDefaultsController, 因此iOS中的NSUserDefaultes的改变就只能通过notification实现了.
绑定NSUserDefaultes中的value
这里介绍一种在Mac 开发中比较常见的使用场景, 例如:我们可以修改应用的快捷键, 而快捷键的具体值是存储在NSUserDefaultes中的,然后修改的快捷键需要实时显示出来, 那么我们就可以bind NSUserDefaultes中的值, 下面介绍两种方式的区别:
例如: 我们使用Label去绑定具体的值, 当我们修改NSUserDefaultes中的之后, 我们可以看看Label的只有没有发生变化, 从而查看两者的区别.
[self.groupOldValueLabel bind:NSValueBinding toObject:self.groupDefaultesController withKeyPath:[@"values." stringByAppendingString:GROUP_VALUE_KEY_STRING] options:nil];
[self.sharedOldValueLabel bind:NSValueBinding toObject:self.sharedDefaultesController withKeyPath:[@"values." stringByAppendingString:SHARED_VALUE_KEY_STRING] options:nil];
在我测试的demo中, App Group中的只修改后, 没办法同步到Label上, 而StandardUserDefaults得只修改后, 是可以直接修改Label值得, 具体的实现, 大家可以下载demo查看, 因此, 这里得出的结论就是: StandardUserDefaults可以通过bind的形式直接反应值得变化, 而App Group中的则不可以, 这也是我之前开发过程中遇到的问题, 因此, 如果出现这种情况, 建议大家使用StandardUserDefaults来存储那些需要bind值得value.
总结
本文介绍的内容主要适用Mac开发, 在iOS开发中, 如果需要监听NSUserDefaultes的变化, 建议直接使用NSUserDefaultsDidChangeNotification监听的形式, 这也是Mac 和 iOS开发不一样的地方, 二者也是有很多不一样的地方.
希望本文的介绍, 能够让大家对NSUserDefaultes有进一步深入的了解, 特别是App Groups中的NSUserDefaultes也是很不一样的, 希望对大家有帮助.