• 关于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);
  • 相关阅读:
    [Unity3D]Animation说明
    [Unity3D]Shader说明
    [AR+Vuforia]学习笔记
    [Android]ListView学习笔记
    [Android]优化相关
    [Android]学习笔记之布局
    [Android]快捷键
    [Android]学习笔记Activity_001
    [Unreal]学习笔记之灯光说明
    什么是Hystrix,Hystrix如何使用
  • 原文地址:https://www.cnblogs.com/yzvictory/p/5762483.html
Copyright © 2020-2023  润新知