zoukankan      html  css  js  c++  java
  • 数据存储

    "IOS数据存储的方式有哪些"

    1.plist

    2.preference用户偏好设置

    3.NSKeyedArchiver(归档)

    4.sqlite

    5.coredata

     

    "plist文件存储"

    应⽤用沙盒结构分析

    应⽤用程序包:(上图中的Layer)包含了所有的资源⽂文件和可执⾏行⽂文件 Documents:保存应⽤用运⾏行时⽣生成的需要持久化的数据,iTunes同步设备时会

    备份该⽬目录。例如,游戏应⽤用可将游戏存档保存在该⽬目录
    

    tmp:保存应⽤用运⾏行时所需的临时数据,使⽤用完毕后再将相应的⽂文件从该⽬目录删 除。应⽤用没有运⾏行时,系统也可能会清除该⽬目录下的⽂文件。iTunes同步设备时 不会备份该⽬目录

    Library/Caches:保存应⽤用运⾏行时⽣生成的需要持久化的数据,iTunes同步设 备时不会备份该⽬目录。⼀一般存储体积⼤大、不需要备份的⾮非重要数据

    Library/Preference:保存应⽤用的所有偏好设置,iOS的Settings(设置) 

    应⽤用会在该⽬目录中查找应⽤用的设置信息。iTunes同步设备时会备份该⽬目录 

    ● 沙盒根⺫⽬目录:NSString*home=NSHomeDirectory();

    ● Documents:(2种⽅方式)

    ● 利⽤用沙盒根⺫⽬目录拼接”Documents”字符串
    NSString *home = NSHomeDirectory();
    NSString *documents = [home stringByAppendingPathComponent:@"Documents"];

    // 不建议采⽤用,因为新版本的操作系统可能会修改⺫⽬目录名

    ● 利⽤用NSSearchPathForDirectoriesInDomains函数
    // NSUserDomainMask 代表从⽤用户⽂文件夹下找
    // YES 代表展开路径中的波浪字符“~”
    NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO);

    // 在iOS中,只有⼀一个⺫⽬目录跟传⼊入的参数匹配,所以这个集合⾥里⾯面只有⼀一个元素

    NSString *documents = [array objectAtIndex:0]; 

    ● tmp:NSString *tmp = NSTemporaryDirectory();

    ● Library/Caches:(跟Documents类似的2种⽅方法)

    ● 利⽤用沙盒根⽬目录拼接”Caches”字符串

    ● 利⽤用NSSearchPathForDirectoriesInDomains函数(将函数的第2个参数改 为:NSCachesDirectory即可)

    ● Library/Preference:通过NSUserDefaults类存取该⽬目录下的设置信息 

    ● 属性列表是⼀一种XML格式的⽂文件,拓展名为plist

    ● 如果对象 是NSString、NSDictionary、NSArray、NSData、NSNumber 等类型,就可以使⽤用writeToFile:atomically:⽅方法直接将对象 写到属性列表⽂文件中 

    ● 将⼀一个NSDictionary对象归档到⼀一个plist属性列表中

    // 将数据封装成字典
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];

    [dict setObject:@"⺟母鸡" forKey:@"name"];

    [dict setObject:@"15013141314" forKey:@"phone"];

    [dict setObject:@"27" forKey:@"age"];
    // 将字典持久化到Documents/stu.plist⽂文件中

    [dict writeToFile:path atomically:YES]; 

     

    ● 成功写⼊入到Documents⽬目录下
    ● ⽤用⽂文本编辑器打开,⽂文件内容为: 

     

    读取属性列表,恢复NSDictionary对象
    // 读取Documents/stu.plist的内容,实例化NSDictionary

    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];

    NSLog(@"name:%@", [dict objectForKey:@"name"]);

    NSLog(@"phone:%@", [dict objectForKey:@"phone"]);
    NSLog(@"age:%@", [dict objectForKey:@"age"]);
    ● 打印信息如下 

    1.字符串 数组 字典 可以直接存储数据在一个文件

    2.掌握沙盒备目录的作用以及目录路径获取方式

    // Document [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] 持久化数据,比如:文件

    // 缓存 [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 微博,另一个设备不会备份

    // 临时 NSTemporaryDirectory(); 比如电影。看完之后不看了

    // 主目录  NSHomeDirectory();

    3.不是所有对象都可以保存到plist文件中,要有实现writeFile方法才可以

    4.学会使用SimPholders2打开沙盒目录

    ViewController.m

    //

    //  ViewController.m

    //  A05.plist文件存储

    //

    //  Created by huan on 16/1/22.

    //  Copyright © 2016 huanxi. All rights reserved.

    //

     

    #import "ViewController.h"

    #import "Contact.h"

    @interface ViewController ()

    @property (nonatomic, copy) NSString *plistPath;

    @end

     

    @implementation ViewController

    //沙盒路径的方法:(1)前往(2)终端+open+enter(3)第三方框架

    //懒加载

    -(NSString *)plistPath{

        if (!_plistPath) {

            NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

            _plistPath = [doc stringByAppendingPathComponent:@"data.plist"];

        }

        return _plistPath;

    }

    - (void)viewDidLoad {

        [super viewDidLoad];

        

    //    NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

    //    NSLog(@"%@", doc);

    ////    NSLog(@"%@", NSHomeDirectory());

    //    NSString *plistPath = [doc stringByAppendingPathComponent:@"data.plist"];

        //读取

    //    NSArray *array = [NSArray arrayWithContentsOfFile:plistPath];

    //    NSLog(@"%@", array);

        

        //获取缓存路径(cache

        NSString * cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

        NSLog(@"%@", cachePath);

        

        //获取临时路径(tmp

        NSString *tmpPath = NSTemporaryDirectory();

        NSLog(@"%@", tmpPath);

        //主目录

        NSString *homePath = NSHomeDirectory();

        NSLog(@"%@", homePath);

    }

     

    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    //    //把数据保存到沙盒的一个plist文件里

    ////    NSArray *data = @[@"asd", @"asds"];

    //    NSDictionary *data = @{@"name":@"zhangsan",@"age":@23};

    //    //获取document目录,用户主目录

    //    NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

    //    NSLog(@"%@", doc);

    ////    NSLog(@"%@", NSHomeDirectory());

    //    NSString *plistPath = [doc stringByAppendingPathComponent:@"data.plist"];

    //    //把数据写入一个文件

    //    [data writeToFile:plistPath atomically:YES];

    //    //读取

    //    NSArray *array = [NSArray arrayWithContentsOfFile:plistPath];

    //    NSLog(@"%@", array);

        [self testDictionary];

        [self testString];

        //不是说有对象都可使用writeToFile方法

        Contact *contact = [[Contact alloc] init];

        contact.name = @"zhangsan";

     

    }

     

    -(void)testString{

        NSString *data = @"aabc";

        //写字符串

        [data writeToFile:self.plistPath atomically:YES encoding:NSUTF8StringEncoding error:nil];

        //读字符串

        NSString *str = [NSString stringWithContentsOfFile:self.plistPath encoding:NSUTF8StringEncoding error:nil];

        NSLog(@"%@", str);

        

    }

     

    -(void)testDictionary{

        //把数据保存到沙盒的一个plist文件里

        NSDictionary *data = @{@"name":@"zhangsan",@"age":@23};

        //把数据写入一个文件

        [data writeToFile:_plistPath atomically:YES];

        //读取

        NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:self.plistPath];

        NSLog(@"%@", dict);

    }

    /**

     * 测试数组存储在一个plist文件

     */

    -(void)testArray{

        //把数据保存到沙盒的一个plist文件里

            NSArray *data = @[@"asd", @"asds"];

    //    NSDictionary *data = @{@"name":@"zhangsan",@"age":@23};

        //获取document目录,用户主目录

    //    NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

    //    NSLog(@"%@", doc);

    //    //    NSLog(@"%@", NSHomeDirectory());

    //    NSString *plistPath = [doc stringByAppendingPathComponent:@"data.plist"];

        //把数据写入一个文件

        [data writeToFile:_plistPath atomically:YES];

        //读取

        NSArray *array = [NSArray arrayWithContentsOfFile:self.plistPath];

        NSLog(@"%@", array);

     

        

    }

     

    //查看沙盒路径

    //1.控制台打印沙盒的路径,使用finder-前往-文件夹 打开

    //2.控制台打印沙盒的路径,打开终端 Open + 路径

    //3.使用simholers工具

    //4.可以断点 输入po NSHomeDirectory

     

    @end

    Contact.h

    #import <Foundation/Foundation.h>

     

    @interface Contact : NSObject

     

    @property (nonatomic, copy) NSString *name;

     

    @end

     

     

     

    "用户偏好设置"

    很多iOS应⽤用都⽀支持偏好设置,⽐比如保存⽤用户名、密码、字体⼤大⼩小等设置,iOS 提供了⼀一套标准的解决⽅方案来为应⽤用加⼊入偏好设置功能

    ● 每个应⽤用都有个NSUserDefaults实例,通过它来存取偏好设置

    ● ⽐比如,保存⽤用户名、字体⼤大⼩小、是否⾃自动登录

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    [defaults setObject:@"itcast" forKey:@"username"];
    [defaults setFloat:18.0f forKey:@"text_size"];

    [defaults setBool:YES forKey:@"auto_login"]; 

    ● 读取上次保存的设置
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

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

    ● 注意:UserDefaults设置数据时,不是⽴立即写⼊入,⽽而是根据时间戳定时地把缓存中

    的数据写⼊入本地磁盘。所以调⽤用了set⽅方法之后数据有可能还没有写⼊入磁盘应⽤用程序

    就终⽌止了。出现以上问题,可以通过调⽤用synchornize⽅方法强制写⼊入

    [defaults synchornize]; 

    1.ios中有个NSUserDefaults对象有可保存数据,我们称为用户偏好设置

    2.通过[NSUserDefaults standardUserDefaults]可以获取用户偏好设置对象,保存字符串 布尔值 int等数据

    3.保存数据时,一定要调用synchronize,因为数据要及时保存到沙盒的文件中

    /*  NSUserDefaults *defualts = [NSUserDefaults standardUserDefaults];

      

      [defualts setObject:@"zhangsan" forKey:@"username"];

      [defualts setObject:@"123" forKey:@"password"];

      [defualts setBool:YES forKey:@"autoLogin"];

      [defualts setBool:YES forKey:@"rememberPwd"];

      

      //同步

      [defualts synchronize];

    */

    4.掌握用户偏好设置数据的获取,更改,删除

    ViewController.m

    //

    //  ViewController.m

    //  B02.用户偏好设置

    //

    //  Created by huan on 16/1/22.

    //  Copyright © 2016 huanxi. All rights reserved.

    //

     

    #import "ViewController.h"

     

    @interface ViewController ()

     

    @end

     

    @implementation ViewController

     

    - (void)viewDidLoad {

        [super viewDidLoad];

    //    [self delete];

        [self modify];

        

       

    }

     

    -(void)modify{

        //修改 用户偏好设置 数据

        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

        [defaults setObject:@"321" forKey:@"password"];

        

        [defaults synchronize];

         NSLog(@"%@", NSHomeDirectory());

    }

     

    -(void)delete{

        //删除 用户偏好设置 数据

        NSUserDefaults *defautls = [NSUserDefaults standardUserDefaults];

        [defautls removeObjectForKey:@"account"];

        

        //删除记得数据也要调用 同步的方法

        [defautls synchronize];

        NSLog(@"%@", NSHomeDirectory());

    }

     

    -(void)read{

        //读取 用户偏好设置 数据

        NSUserDefaults *defautls = [NSUserDefaults standardUserDefaults];

        NSString *account = [defautls objectForKey:@"account"];

        NSString *password = [defautls objectForKey:@"password"];

        BOOL rememberPwd = [defautls boolForKey:@"rememberPwd"];

        BOOL autoLogin = [defautls boolForKey:@"autoLogin"];

        NSLog(@"%@, %@, %d, %d", account, password, rememberPwd, autoLogin);

    }

     

    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

        //使用偏好设置保存数据

        

        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

        //要保存的数据

        [defaults setObject:@"zhangsan" forKey:@"account"];

        [defaults setObject:@"123" forKey:@"password"];

        [defaults setBool:YES forKey:@"autoLogin"];

        [defaults setBool:YES forKey:@"rememberPwd"];

        

        //调用同步的方法,把数据保存到沙盒文件

        [defaults synchronize];

        

    }

     

     

     

    @end

     

    "NSKeyedArchiver归档"

    ● 如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类 型,可以直接⽤用NSKeyedArchiver进⾏行归档和恢复

    ● 不是所有的对象都可以直接⽤用这种⽅方法进⾏行归档,只有遵守了NSCoding协议 的对象才可以

    ● NSCoding协议有2个⽅方法:

    ● encodeWithCoder:

    每次归档对象时,都会调⽤用这个⽅方法。⼀一般在这个⽅方法⾥里⾯面指定如何归档对象中的每 个实例变量,可以使⽤用encodeObject:forKey:⽅方法归档实例变量

    ● initWithCoder: 每次从⽂文件中恢复(解码)对象时,都会调⽤用这个⽅方法。⼀一般在这个⽅方法⾥里⾯面指定如何解

    码⽂文件中的数据为对象的实例变量,可以使⽤用decodeObject:forKey⽅方法解码实例变量 

    • 归档⼀一个NSArray对象到Documents/array.archive NSArray *array = [NSArray arrayWithObjects:@”a”,@”b”,nil];

    [NSKeyedArchiver archiveRootObject:array toFile:path];

    • 归档成功 

    @interface Person : NSObject<NSCoding>

    @property (nonatomic, copy) NSString *name;

    @property (nonatomic, assign) int age;

    @property (nonatomic, assign) float height;

    @end 

    @implementation Person
    - (void)encodeWithCoder:(NSCoder *)encoder {
    

    [encoder encodeObject:self.name forKey:@"name"];

    [encoder encodeInt:self.age forKey:@"age"];

    [encoder encodeFloat:self.height forKey:@"height"];

    }
    - (id)initWithCoder:(NSCoder *)decoder {
    

    self.name = [decoder decodeObjectForKey:@"name"];

    self.age = [decoder decodeIntForKey:@"age"];

    self.height = [decoder decodeFloatForKey:@"height"]; return self;

    }
    - (void)dealloc {
    
       [super dealloc];
    
       [_name release];
    }
    

    @end 

    ● 归档(编码)
    Person *person = [[[Person alloc] init] autorelease]; person.name = @"MJ";
    person.age = 27;
    person.height = 1.83f;
    [NSKeyedArchiver archiveRootObject:person toFile:path];

    ● 恢复(解码)
    Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; 

    ● 如果⽗父类也遵守了NSCoding协议,请注意:
    ● 应该在encodeWithCoder:⽅方法中加上⼀一句 [super encodeWithCode:encode];

    确保继承的实例变量也能被编码,即也能被归档

    ● 应该在initWithCoder:⽅方法中加上⼀一句

    self = [super initWithCoder:decoder];

    确保继承的实例变量也能被解码,即也能被恢复

    NSData

    ● 使⽤用archiveRootObject:toFile:⽅方法可以将⼀一个对象直接写⼊入到

    ⼀一个⽂文件中,但有时候可能想将多个对象写⼊入到同⼀一个⽂文件中,那么就

    要使⽤用NSData来进⾏行归档对象

    ● NSData可以为⼀一些数据提供临时存储空间,以便随后写⼊入⽂文件,或者存

    放从磁盘读取的⽂文件内容。可以使⽤用[NSMutableData data]创建可

    变数据空间 

    
    

    NSData-归档2个Person对象到同⼀一⽂文件中 

    ● 归档(编码)

    // 新建⼀一块可变数据区

    NSMutableData *data = [NSMutableData data];

    // 将数据区连接到⼀一个NSKeyedArchiver对象

    NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];

    // 开始存档对象,存档的数据都会存储到NSMutableData中

    [archiver encodeObject:person1 forKey:@"person1"];
    [archiver encodeObject:person2 forKey:@"person2"];
    // 存档完毕(⼀一定要调⽤用这个⽅方法)

    [archiver finishEncoding];
    // 将存档的数据写⼊入⽂文件
    [data writeToFile:path atomically:YES]; 

    NSData-从同⼀一⽂文件中恢复2个Person对象 

    ● 恢复(解码)

    // 从⽂文件中读取数据

    NSData *data = [NSData dataWithContentsOfFile:path];

    // 根据数据,解析成⼀一个NSKeyedUnarchiver对象

    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];

    Person *person1 = [unarchiver decodeObjectForKey:@"person1"];

    Person *person2 = [unarchiver decodeObjectForKey:@"person2"]; // 恢复完毕
    [unarchiver finishDecoding]; 

    
    

    利用归档实现深复制



    /*什么叫归档 归档就是把数据保存到一个文件中*/

    1.使用NSKeyedArchiver可以将NSArray NSDictiony NSString等对象归档到一个文件

    2.只有实现了NSCoding协议的对象才可使用NSKeyedArchiver进行归档

     

    3.将模型对象保存到一个文件时,对象要遵守NSCoding协议,并实现NSKeyedArchiverencodeWithCoder方法,

    4.从归档文件里读取对象时要实现NSCodinginitWithCoder方法

    5.ios中,控制器,控件都继承NSCoding,storyboard/xib都是使用NSKeyedArchiver进行归档的

    ViewController.m

    //

    //  ViewController.m

    //  B03.NSCoding

    //

    //  Created by huan on 16/1/22.

    //  Copyright © 2016 huanxi. All rights reserved.

    //

     

    #import "ViewController.h"

    #import "Contact.h"

    @interface ViewController ()

    /**

     * NSKeyedArchiver 保存数据

     * NSKeyedUnarchiver 读取数据

     */

    @property (nonatomic, copy) NSString *plistPath;

    -(IBAction)saveData;

    -(IBAction)readData;

     

    @end

     

    @implementation ViewController

     

    -(NSString *)plistPath{

        if (!_plistPath) {

            NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

            _plistPath = [doc stringByAppendingPathComponent:@"data.plist"];

        }

        return _plistPath;

    }

     

    //-(id)initWithCoder:(NSCoder *)aDecoder{

    //    if (self = [super init]) {

    //        

    //    }

    //    return  self;

    //}

    - (void)viewDidLoad {

        [super viewDidLoad];

        //保存字典

        [self testDict];

        //读字典

        NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithFile:self.plistPath];

        NSLog(@"%@", dict);

        

    }

     

    -(IBAction)saveData{

        //使用归档方法保存数据

    //    NSArray *data = @[@"abc", @23];

    //    NSDictionary *data = @{@"name":@"zhangs", @"height":@90};

    //    

    //    //直接把一个对象保存到沙盒里

    //    [NSKeyedArchiver archiveRootObject:data toFile:self.plistPath];

    //    NSLog(@"%@", NSHomeDirectory());

        

        Contact *contact = [[Contact alloc] init];

        contact.name = @"张三";

        contact.age = 27;

        contact.tel = @"13512312345";

        [NSKeyedArchiver archiveRootObject:contact toFile:self.plistPath];

        

        NSLog(@"%@", NSHomeDirectory());

     

    }

     

    -(IBAction)readData{

        //读数据

        Contact *contact = [NSKeyedUnarchiver unarchiveObjectWithFile:self.plistPath];

        NSLog(@"%@ %d %@",contact.name, contact.age, contact.tel);

        

    }

    /**

     * 测试 系统的NSDictionary NSArray的归档

     * 只有 对象 遵守了NSCoding协议才可以使用NSKeyedArchiver进行数据存储

     */

    -(void)testDict{

        //使用归档方法保存数据

        NSDictionary *data = @{@"name":@"zhangs", @"height":@90};

        

        //直接把一个对象保存到沙盒里

        [NSKeyedArchiver archiveRootObject:data toFile:self.plistPath];

        NSLog(@"%@", NSHomeDirectory());

        

    }

     

    @end

     Contact.h

    #import <Foundation/Foundation.h>

    #import "Person.h"

    @interface Contact : Person

     

    @property (nonatomic, copy) NSString *tel;//当有属性是必须实现NSCondig的两种方法。

     

    @end

    Contact.m

    #import "Contact.h"

     

    @implementation Contact

    -(void)encodeWithCoder:(NSCoder *)aCoder{

        [super encodeWithCoder:aCoder];

        //添加自己属性的存储

        [aCoder encodeObject:self.tel forKey:@"tel"];

    }

     

    -(id)initWithCoder:(NSCoder *)aDecoder{

        if (self = [super initWithCoder:aDecoder]) {

            //子类实现initWithCoder方法时,self 不要写 self = [super init];

            self.tel = [aDecoder decodeObjectForKey:@"tel"];

        }

        return self;

    }

    @end

    Person.h

    #import <Foundation/Foundation.h>

     

    @interface Person : NSObject<NSCoding>

     

    @property (nonatomic, copy) NSString *name;

    @property (nonatomic, assign) int age;

     

    @end

    Person.m

    #import "Person.h"

     

    @implementation Person

     

    -(void)encodeWithCoder:(NSCoder *)aCoder{

        //指定 每个属性 怎么存储

        [aCoder encodeObject:self.name forKey:@"name"];

        [aCoder encodeInt:self.age forKey:@"age"];

    }

     

    -(id)initWithCoder:(NSCoder *)aDecoder{

        //读取 数据 设置每个属性

        if (self = [super init]) {

            self.name = [aDecoder decodeObjectForKey:@"name"];

            self.age = [aDecoder decodeIntForKey:@"age"];

        }

        return self;

    }

     

     

    @end

     

  • 相关阅读:
    Mybatis学习-ResultMap
    MySql模糊查询 concat()函数
    Spring学习-依赖注入
    Struts2学习-struts执行过程简述
    Struts2学习-jsp中超链接传参问题
    Struts2学习-struts.xml文件配置
    第四次作业
    第三次作业
    Django -Ajax
    Django -ORM
  • 原文地址:https://www.cnblogs.com/Lu2015-10-03/p/5164712.html
Copyright © 2011-2022 走看看