Mac开发中NSUserDefaults用法解析

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文件夹.

实现方式区别

  1. 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也是很不一样的, 希望对大家有帮助.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值