iOS 数据持久化

作者: 升级打怪啊怪 | 来源:发表于2016-07-24 00:19 被阅读98次
    iOS应用沙盒机制

    iOS应用程序只能在为该程序创建的文件系统中读取文件,不可以去其他地方访问,此区域被称为沙盒,所以所有的非代码文件都要保存在此,例如图像、图标、声音、属性列表、文本文件等。
    应用沙盒机制下,每个应用程序都有自己的存储空间;应用程序不能翻过自己的围墙去访问别的存储空间的内容;应用程序请求的数据都要通过权限检测,假如不符合条件的话,不会被放行。

    XCode中的应用沙盒目录:

    1、模拟器的位置:
    /Users/username/Library/Developer/CoreSimulator/Devices/EBABD400-5D00-49F8-AB77-73ACB15B83CD
    devices目录下存放着XCode中包含的模拟器,在device.plist中可以看到该模拟器的基本信息。

    ![Upload Snip20160723_39.png failed. Please try again.]

    2、每个应用的沙盒目录:
    /Users/username/Library/Developer/CoreSimulator/Devices/EBABD400-5D00-49F8-AB77-73ACB15B83CD/data/Containers/Data/Application/

    ![Upload Snip20160723_42.png failed. Please try again.]

    NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];]
    
    应用沙盒的结构:

    1、Documents :保存应用运行时生成的需要持久化的数据,iTunes同步设备时 会备份该目录 。例如,游戏应用可将游戏存档保存在该目录
    2、tmp :保存应用运行时所需的 临时数据 ,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录
    3、Library/Caches :保存应用运行时生成的需要持久化的数据,iTunes同步设备时 不会备份该目录 。一般存储体积大、不需要备份的非重要数据
    4、Library/Preference :保存应用的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息。iTunes同步设备时 会备份该目录

    获取当前应用沙盒的目录:
    NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    

    =================我是分隔线=================

    切正题吧,以下介绍几个轻量级的数据存储方式。

    一、plist(property list)

    它是一种用来存储串行化后的对象的文件,是xml格式的。
    使用场景:plist文件通常用于存储用户设置,也可以用于存储捆绑的信息。
    支持的数据类型:可以被序列化的对象类型:

    NSArray/NSMutableArray;
    NSDictionary/NSMutableDictionary;
    NSData/NSMutableData;
    NSString/NSMutableString;
    NSNumber;

    存取:
    使用writeToFile:automically:方法直接将对象写到plist文件中。
    可以使用NSArray或者NSDictionary来取plist里面的数据:
    [NSArray arrayWithContentsOfFile:filePath];

    二、Preference

    存储目录在library/Preferences,是一个plist文件。适合存储轻量级的本地数据。
    支持的数据格式有:

    NSNumber(Integer、Float、Double),NSString,NSDate,NSArray,NSDictionary,BOOL类型

    存:

    NSUserDefaults *defaults = [NSUserDefaults  standardUserDefaults];
    [defaults  setObject:@"itcast"  forKey:@"username"];
    [defaults  setFloat:18.0f  forKey:@"text_size"];
    [defaults  setBool:YES  forKey:@"auto_login"];
    

    UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。可以通过调用synchornize方法强制写入

    [defaults synchornize];
    

    取:

    NSString *username = [defaults  stringForKey:@"username"];
    float textSize = [defaults floatForKey:@"text_size"];
    BOOL autoLogin = [defaults  boolForKey:@"auto_login"];
    

    三、NSKeyedArchiver

    归档(又名序列化),把对象转为字节码,以文件的形式存储到磁盘上;程序运行过程中或者当再次重写打开程序的时候,可以通过解归档(反序列化)还原这些对象。

    plist只能存储Foundation框架中的对象,归档除了可以归档Foundation框架中的对象以外,还可以归档实现了NSCoding协议的自定义对象。
    归档和解归档其中任意对象都需要归档和解归档整个文件。
    归档后的文件是加密的,所以归档文件的扩展名可以随意取。

    归档方式分三种
    1、对Foundation框架中对象进行归档。

    一次只能归档一个对象,如果是多个对象归档需要分开进行。

    // 归档:
    NSArray *archiveAry = @[@"jereh",@"ios"];
    [NSKeyedArchiver archiveRootObject: archiveAry toFile:filePath];
    // 解归档:
    [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    

    2、对自定义的内容进行归档。

    在带键的归档中,每个归档字段都有一个key值,解归档时key值要与归档时key值匹配。
    带键归档可以一次存储多个对象。

    //归档:
    //1. 使用NSData存放归档数据
    NSMutableData *archiverData = [NSMutableData data];
    //2. 创建归档对象
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:archiverData];
    //3. 添加归档内容 (设置键值对) 
    [archiver encodeObject:@"jereh" forKey:@"name"]; [archiver encodeInt:20 forKey:@"age"]; [archiver encodeObject:@[@"ios",@"oc"] forKey:@"language"];
    //4. 完成归档 
    [archiver finishEncoding];
    //5. 将归档的信息存储到磁盘上
    if ([archiverData writeToFile:filePath atomically:YES]) {
         NSLog(@"archiver success");
    }
    //解归档:
    //1. 从磁盘读取文件,生成NSData实例
    NSData *unarchiverData = [NSData dataWithContentsOfFile:filePath];
    //2. 根据Data实例创建和初始化解归档对象
    NSKeyedUnarchiver *unachiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:unarchiverData];
    //3. 解归档,根据key值访问
    NSString *name = [unachiver decodeObjectForKey:@"name"];
    int age = [unachiver decodeIntForKey:@"age"];
    NSArray *ary = [unachiver decodeObjectForKey:@"language"];
    

    3、对自定义的对象进行归档

    自定义的对象归档需要实现NSCoding协议,并且实现协议中的方法。
    NSCoding协议中有两个方法:encodeWithCoder方法对对象属性进行编码,在对象归档时调用;initWithCoder方法解码归档数据来初始化对象,在对象解归档时调用。

    @interface Student : NSObject <NSCoding>
    @property (nonatomic, assign) int idNum;
    @property (nonatomic, copy) NSString *name;
    @end
    
    @implementation Student
    // 编码 对对象属性进行编码的处理
    - (void)encodeWithCoder:(NSCoder *)aCoder{
        [aCoder encodeInt:_idNum forKey:@“id"];
        [aCoder encodeObject:_name forKey:@“name"];
    }
    // 解码 解码归档数据来初始化对象
    - (id)initWithCoder:(NSCoder *
    )aDecoder{   
     if (self = [super init]) {
            _idNum = [aDecoder decodeIntForKey:@“id"];
            _name = [aDecoder decodeObjectForKey:@“name"];
        }    return self;
    }
    @end
    

    相关文章

      网友评论

        本文标题:iOS 数据持久化

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