美文网首页111iOS开发iOS学习
数据存储之NSUserDefaults

数据存储之NSUserDefaults

作者: 梦回蓝桥 | 来源:发表于2016-11-25 19:23 被阅读1847次

    ios开发常用的五种数据存储方式:

    • plist
    • NSUserDefaults
    • NSKeyedArchiver
    • FMDB
    • CoreData
      这篇文章我们主要回顾NSUserDefaults的使用

    NSUserDefaults

    NSUserDefaults是一个单例,在整个程序中只有一个实例对象,它可以用于数据的永久存储,主要面向的是一些简单数据类型,如:NSNumber、NSString、NSArray、NSDictionary ...

    1.值得注意的是对相同的key赋值约等于一次覆盖,所以请保证key的唯一性

    以NSString为例:
    存:
    NSUserDefaults是定时把缓存中的数据写入磁盘的,而不是即时写入,为了防止在写完NSUserDefaults后程序退出导致的数据丢失,可以在写入数据后使用synchronize强制立即将数据写入磁盘.

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *password = @"123456";
    [defaults setObject:password forKey:@"userPassword"];
    [defaults synchronize];

    取:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *password = [defaults objectForKey:@"userPassword"];

    删除:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults removeObjectForKey:@"userPassword"];

    2.同时我们还要注意NSUserDefaults存储的对象全是不可变的,就算你存的时候是可变的,最后都会被转成不可变的

    以数组为例:
    存:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableArray *mutableArr = [NSMutableArray arrayWithObjects:@"1",@"2",@"3", nil];
    NSArray *arr = [NSArray arrayWithArray:mutableArr];
    [defaults setObject:arr forKey:@"mutableArr"];//这里最好存放不可变的(arr)

    取 :(错误的写法):

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableArray *mutableArr = [defaults objectForKey:@"mutableArr"];

    取:(正确的写法):

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableArray *mutableArr = [NSMutableArray arrayWithArray:[defaults objectForKey:@"mutableArr"]];

    没经过论证的观点很容易扯到蛋!接着上面的存数据我们来证实一下"取数据"的结果:

    //存
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableArray *mutableArr = [NSMutableArray arrayWithObjects:@"1",@"2",@"3", nil];
    NSArray *arr = [NSArray arrayWithArray:mutableArr];
    [defaults setObject:arr forKey:@"mutableArr"];//这里最好是不可变的,你存mutableArr(可变)也可
    //取:错误的姿势(不要直接赋值给可变数组(NSMutableArray))
    NSMutableArray *getmutableArr = [defaults objectForKey:@"mutableArr"];
    NSLog(@"%@",getmutableArr);

    到这里我们运行一下程序:

    2016-11-25 12:11:11.784 DataStorageDemo[18196:1134737] (
    1,
    2,
    3
    )

    也没什么bug啊,可是!可是!可是你向这个可变数组中加入数据试试:

    [getmutableArr insertObject:@"4" atIndex:0];
    NSLog(@"%@",getmutableArr);

    屏幕快照 2016-11-25 下午12.15.34.png
    程序崩溃了...了...了...
    然后我们修改一下代码:

    //取:正确的姿势-将取出的不可变数组赋值给可变数组
    NSMutableArray *getmutableArr = [NSMutableArray arrayWithArray:[defaults objectForKey:@"mutableArr"]];
    [getmutableArr insertObject:@"4" atIndex:0];
    NSLog(@"%@",getmutableArr);

    程序运行结果如下:

    2016-11-25 12:31:51.670 DataStorageDemo[18283:1142923] (
    4,
    1,
    2,
    3
    )

    聪明如你,此刻该明白了!如果此时你想将修改后的数组存入NSUserDefaults,很简单:

    //还记得之前提到的相同的key约等于一次覆盖吗?
    [defaults setObject:getmutableArr forKey:@"mutableArr" ];

    3.NSUserDefaults应用场景

    (1)好多app都带有轮播图功能


    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    //判断是否第一次启动
    if (![[NSUserDefaults standardUserDefaults]boolForKey:@"firstLogin"]) {
    [[NSUserDefaults standardUserDefaults]setBool:YES forKey:@"firstLogin"];
    LoadViewController *loadVC = [[LoadViewController alloc]init];
    UINavigationController *naVC = [[UINavigationController alloc]initWithRootViewController:loadVC];
    self.window.rootViewController = naVC;
    }else{
    RootViewController *rootVC = [[RootViewController alloc]init];
    UINavigationController *naVc = [[UINavigationController alloc]initWithRootViewController:rootVC];
    self.window.rootViewController = naVc;
    }
    [self.window makeKeyAndVisible];
    return YES;
    }

    在这里我们用NSUserDefaults存储了一个bool值对象,如果是第一次进入app,取出的bool则为nil(因为之前没存过),我们就进入加载轮播图的vc(LoadViewController),并赋值bool为yes,存入沙盒.
    等再次进入app时,因为我们之前为bool赋值yes,所以boolForKey:@"firstLogin"就为不为空了,我们直接进入loginVC(在demo中是RootViewController)进行操作.
    简书中涉及到的技术点demo中都有,等更新完五种存储之后,我会将代码上传到git供大家参考

    (2) 自动登录

    我们知道登陆成功之后我们通常会存储一些用户的个人信息(用NSUserDefaults一样存储这种自定义类型的数据,只是需要转成nsdata,推荐使用NSKeyedArchiver(序列化),下一章介绍!)
    登陆成功后我们就可以存储一个字符串用来识别当前是登陆状态还是解绑状态

    -(void)loginBtnAction
    {
    //实际开发中执行一些请求操作....
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:@"这个字符串do you self" forKey:@"isLogin"];
    }

    之后再打开app时我们通过判断defaults中key对应的value值是否为空就知道当前是登陆状态还是解绑状态了

    if (![[NSUserDefaults standardUserDefaults]objectForKey:@"isLogin"]) {
    //未登陆
    }else{
    //已登陆
    }

    demo地址:

    https://github.com/skyxian/DataStorageDemo

    相关文章

      网友评论

      • 大斌小姜:synchronize is deprecated,文档中现在已经不建议使用这个同步方法了

      本文标题:数据存储之NSUserDefaults

      本文链接:https://www.haomeiwen.com/subject/gccipttx.html