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也是很不一樣的, 希望對大家有幫助.

發佈了40 篇原創文章 · 獲贊 6 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章