首页 > 其他 > 详细

数据存储

时间:2016-01-27 23:10:31      阅读:446      评论:0      收藏:0      [点我收藏+]

"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

 

数据存储

原文:http://www.cnblogs.com/Lu2015-10-03/p/5164712.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!