關於NSUserDefaults的秘密


  •    NSUserDefaults 簡介

  在日常開發中經常遇到本地存儲,存儲的方式有很多,今天我們就來看看NSUserDefaults,NSUserDefaults是一個輕量級的本地化存儲的一個類。可以用它來保存一些偏好設置,其保存路徑為Library/Preferences。注意這個存儲並沒有加密,so。

  •  NSUserDefaults常用的方法

  NSUserDefaults常用的方法,使用和NSMutableDictionary的一些方法類似。如下,看不懂的請自行百度

//設置
- (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;

- (void)setURL:(nullable NSURL *)url forKey:(NSString *)defaultName NS_AVAILABLE(10_6, 4_0);
- (void)setObject:(nullable id)value forKey:(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 NS_AVAILABLE(10_6, 4_0);

  調用set的方法后,如果需要馬上同步需要synchronize方法。注意這個方法不要太頻繁調用。如果不調用synchronize,系統會每個一個時間段自動保存。

  •   NSUserDefaults高級用法
  1. 保存自定義對象

  NSUserDefaults只支持基本數據類型,如果需要保存自定義的對象,就需要借助NSKeyedArchiver將對象歸檔成NSData,然后再用[useDefault setObject: forKey:];方法保存

  

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        self.str = [aDecoder decodeObjectForKey:@"str"];
        self.interget = [aDecoder decodeIntegerForKey:@"interget"];
        self.flo = [aDecoder decodeDoubleForKey:@"flo"];
    }
    return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self.str forKey:@"str"];
    [aCoder encodeInteger:self.interget forKey:@"interget"];
    [aCoder encodeDouble:self.flo forKey:@"flo"];
}
- (NSString *)description
{
    return [NSString stringWithFormat:@"%@;%ld,%f",self.str,(long)self.interget,self.flo];
}
    Demo *demo = [[Demo alloc]init];
    demo.str = @"test";
    demo.interget = 10;
    demo.flo = 12.0f;
    
    NSData *demoData = [NSKeyedArchiver archivedDataWithRootObject:demo];
    
    [useDefault setObject:demoData forKey:@"demo"];
    [useDefault synchronize];
    
    NSData *getData = [useDefault objectForKey:@"demo"];
    
    Demo *getDemo = [NSKeyedUnarchiver unarchiveObjectWithData:getData];
    NSLog(@"%@",getDemo);

  2.數據共享 

  app group 中的數據共享,至於怎么新建group,參考https://onevcat.com/2014/08/notification-today-widget/,基本的思路如下

// appA中
    NSUserDefaults *shareDefaultA = [[NSUserDefaults alloc]initWithSuiteName:@"com.storage.demo"];
    [shareDefaultA setObject:@"appA" forKey:@"shareKey"];
    // appB中
    NSUserDefaults *shareDefaultB = [[NSUserDefaults alloc]initWithSuiteName:@"com.storage.demo"];
    NSString *value = [shareDefaultB objectForKey:@"shareKey"];

  這里就能解釋,同一個公司的app,裝了一個之后,在裝另一個,就會自動登錄的功能。initWithSuiteName會在Library/Preference下新建一個以name為名字的plist文件。[NSUserDefaults standardUserDefaults]是以bundle id為名字的一個plist文件。利用這個我們可以給每一個用戶新建一個偏好設置的文件,保存皮膚,字體等,不同的用戶登錄就會有不同的效果。

  • NSUserDefaults數據清除

  - (void)removePersistentDomainForName:(NSString *)domainName;清除domain下的所有信息。在這里要說一下NSUserDefaults的域,默認包含5個domain,分別是NSArgumentDomain,Application,NSGlobalDomain,Languages,NSRegistrationDomain。

    //清除Application所有的偏好設置,如果domainName是initWithSuiteName的name,則清除name對應的plist文件的內容
    NSString *appDomain = [[NSBundle mainBundle]bundleIdentifier];
    [[NSUserDefaults standardUserDefaults]removePersistentDomainForName:appDomain];
  • NSUserDefaults注意的地方

  當我們獲取偏好設置的值的時候,需要注意,比如如下:[stand boolForKey:@"key1"];如果沒有對應的key1則獲取的值為默認值false。這種情況就有可能和有對應的key,並且對應的值為false時,區分不開,造成的邏輯錯誤。類似的還有[stand integerForKey:@""]等。

  對應的解決辦法是:

NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"true",@"test",@"3",@"inter", nil];
    //注冊一個默認的字典
    [stand registerDefaults:dict];
    
    BOOL isok = [stand boolForKey:@"test"];
    
    NSInteger inter = [stand integerForKey:@"inter"];
    
    NSLog(@"%d,,,,%ld",isok,(long)inter);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM