ios数据持久化

关于数据持久化

数据持久化,字面上的意思来理解,就是将数据存放更长时间。
很显然的,当我们在平时开发中,必然而然的会使用到数据的持久化,但是通用的几种方式,我们应该了然于心。以便于在使用到的时候,能够更好的选择使用哪一种。

通常数据持久化的几种方式

1.NSUserDefaults
2.NSKeyedArchiver(对象模型归档)
3.SQLite
4.Core Data

1.NSUserDefaults

NSUserDefaults是苹果提供的一种偏好设置的方法,将我们需要的一些偏好设置写道plist文件当中。例如,记录主题设置的模式,是否自动登录等等。
NSUserDefaults是苹果提供的一个单例,使用方法很简单,如下:

////write
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"daytime" forKey:@"themeStyle"];
[defaults synchronize];

////read
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *themeStyle= [defaults objectForKey:@"themeStyle"]

类似于此,NSUserDefaults 还持支NSData,NSString,NSNumber,NSDate,NSArray,NSDictionary这些数据类型。
当然苹果还提供了具体类型的读写方法:

- setBool:forKey:
- setFloat:forKey:
...等

但是,写数据的时候特别注意的是这一句话

[defaults synchronize];

当我们利用NSUserDefaults 来写入数据的时候,系统默认并不是马上就会写道plist里面,但是往往我们需要存一些偏好设置的时候,想法是写进去,plist里面就会马上响应,就可以马上读出来。如果想实现该需求,就需要在我们存储数据的最后面加上synchronize来同步数据到pilst里面。

2.NSKeyedArchiver与沙盒

NSKeyedArchiver 对象归档,就是当我们需要将自定义的类对象进行二进制化归档。而沙盒存储呢,简单的来说,就是将文件给存到本地磁盘中。

NSKeyedArchiver

首先,要使用NSKeyedArchiver归档,就需要实现NSCoding协议。同时实现其序列化和反序列化这两个方法

//反序列化
//从coder中读取数据,保存到相应的变量中
- (id)initWithCoder:(NSCoder *)aDecoder;

// 序列化
//读取实例变量,并把这些数据写到coder中。
-(void)encodeWithCoder:(NSCoder *)coder;

沙盒

关于ios沙盒机制,简单来说就是一个安全权限。默认权限下,苹果只允许IOS应用程序访问程序自己的目录,该目录就称为“沙盒”。
下图是沙河目录

MyApp.app

存放应用程序本身的数据,整个目录是只读的
不会被iTunes同步

Documents

存放应用程序的数据文件(不可再生的)
会被iTunes同步

Documents/Inbox

存放保存由外部应用请求当前应用程序打开的文件
会被同步

Library

苹果建议用来存放默认设置或其它状态信息
会被iTunes同步,但是除了Caches子目录

Library/Caches

主要是缓存文件
不会被iTunes同步

Library/Preferences

应用程序的偏好设置文件。例如NSUserDefaults写的设置数据都会保存到该目录下的一个plist文件中
会被iTunes同步

tmp

各种临时文件,保存应用再次启动时不需要的文件,并且随时有可能被系统清理掉
不会被iTunes同步

简单的使用

了解了NSKeyedArchiver需要什么,沙盒是什么了,下面我们就开始来看代码:

@interface Person: NSObject <NSCoding>
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *sex;
@end

//...
//实现序列化和反序列化
@implementation Person

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.sex forKey:@"sex"];
    
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
    self.name = [aDecoder decodeObjectForKey:@"name"];
    self.sex= [aDecoder decodeObjectForKey:@"sex"];
    
    return self;
}

@end

Person* person=  [[Person alloc] init];
person.name = @"zhu";
person.age = @"man";
];
//归档,调用encodeWithCoder方法 
NSData * perData= [NSKeyedArchiver archivedDataWithRootObject:person];
//读取归档数据,调用initWithCoder
Person* per= [NSKeyedUnarchiver unarchiveObjectWithData:perData];

//也可以将序列化的对象保存到沙盒中
 //获得Document的路径  
NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];  
//拓展名可以自己随便取
NSString *path = [documents stringByAppendingPathComponent:@"person.archiver"];   
[NSKeyedArchiver archiveRootObject:person toFile:path]; 

//读取沙盒中的文件
NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];  
NSString *path = [documents stringByAppendingPathComponent:@"person.archiver"];  
person *person1 = [NSKeyedUnarchiver unarchiveObjectWithFile:path];  


3.SQLite

SQLite是一个轻量级关系数据库,最初的设计目标是用于嵌入式系统,它占用资源非常少.在iOS中,只需要加入li’blibsqlite3.0依赖以及引入sqlite3.h头文件即可。
关于sqlite在ios中的使用,我并没有深入的了解过,所以这里只是简单的介绍下。

4.Core Data

Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象。
至于到底是用coredata还是sqlite,大家是各持己见,但是我觉得还是应该看具体的业务逻辑。不要局限于某一个工具,而是在合适的时候选择合适的方法就好。
关于coredata我们要知道的几个东西

1.NSManagedObjectContext(托管对象上下文)
负责应用和数据库之间的交互,例如增删查改。

2.NSManagedObjectModel(托管对象模型)
负责coredara里面的模型文件

3.NSPersistentStoreCoordinator(持久化存储协调器)
负责添加持久性数据库,例如sqlite,Binary、XML、或In-Memory等。但要注意这点,Binary和XML格式的存储区是Atomic,意思是就算我们只想修改少量的数据,但是在保存的时候还是得将整个文件都写进磁盘。

对于coredata,初学者不要觉得很神奇,简单的想成是一个对象关系的数据库就行了,不需要写sql语句,就能实现数据的存取。
下面是一些简单的使用:

- (IBAction)addClick:(id)sender {
    
    NSLog(@"addClick");
   
    Employee *em = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:self.ctx];
    em.name = @"lisi";
    em.height = @172;
    em.age = @25;
    
    NSError *error = nil;
    [self.ctx save:&error];
    
    if (error) {
        NSLog(@"%@===error", error);
    } else {
        NSLog(@"=====add=success====");
    }
    
}

- (IBAction)readClick:(id)sender {
    
    NSLog(@"readClick");
    
    NSEntityDescription *enty = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.ctx];
    NSFetchRequest *featch = [[NSFetchRequest alloc] init];
    
    [featch setEntity:enty];
    
//    NSPredicate *pre = [NSPredicate predicateWithFormat:@"name=%@",@"lisi"];
//    
//    [featch setPredicate:pre];
    
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"height" ascending:YES];
    featch.sortDescriptors = @[sort];
    
    NSArray *arr = [self.ctx executeFetchRequest:featch error:nil];
    for (Employee *em in arr) {
        NSLog(@"姓名:%@ 身高%@",em.name ,em.height);
    }
}


- (IBAction)deleteClick:(id)sender {
    
    NSLog(@"deleteClick");
    
    NSEntityDescription *enty = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.ctx];
    NSFetchRequest *featch = [[NSFetchRequest alloc] init];
    featch.entity = enty;
    featch.predicate = [NSPredicate predicateWithFormat:@"name=%@",@"lisi"];
    
    NSArray *arr = [self.ctx executeFetchRequest:featch error:nil ];   
    for (Employee *em in arr) {
        NSLog(@"姓名:%@ 身高%@",em.name ,em.height);
        [self.ctx deleteObject:em];
    }
    
    [self.ctx save:nil];
}


- (IBAction)updateClick:(id)sender {
    
    NSLog(@"updateClick");
    
    NSEntityDescription *enty = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.ctx];
    NSFetchRequest *featch = [[NSFetchRequest alloc] init];
    featch.entity = enty;
    featch.predicate = [NSPredicate predicateWithFormat:@"name=%@",@"lisi"];
    
    NSArray *arr = [self.ctx executeFetchRequest:featch error:nil ];
    
    for (Employee *em in arr) {
        NSLog(@"姓名:%@ 身高%@",em.name ,em.height);
        em.name = @"wangwu";
    }
    
    [self.ctx save:nil];
}

- (NSManagedObjectContext *)ctx
{
    if (!_ctx) {
        _ctx = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];        
                
        NSManagedObjectModel *mModel = [NSManagedObjectModel mergedModelFromBundles:nil];
        
        NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mModel];
        
        NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        NSString *url = [path stringByAppendingPathComponent:@"zhu.sqlite"];
        [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:url] options:nil error:nil];
        
        _ctx.persistentStoreCoordinator = coordinator;
    }
    return _ctx;
}

结束语

其实关于ios中数据持久化的使用,不会仅限于此,以上只是一些简单的介绍和使用的方法。在当说到数据持久化的时候,我们脑海中应该蹦出一些自己的理解来。自己心中理一个适合自己的知识结构来帮助我们打理逻辑,然后在实际使用场景的时候,根据具体业务来选择具体使用哪一种数据持久化方案。我认为做开发的不要一脑门的死记硬背,一脑门的按照别人的说的来做。看到别人的逻辑的时候,觉得好的,自己心里领会下,觉得不好的,自己在想想怎么去做会更加完美。千万不要做代码的奴隶,而是以一种艺术家,建筑师又或者设计师的角度来审视代码。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容

  • iOS数据持久化方式 文件 归档(NSKeyedArchiver) 属性列表(NSUserDefaults) 数据...
    向阳的向日葵花阅读 899评论 0 12
  • 1.简介 数据持久存储是一种非易失性存储,在重启动计算机或设备后也不会丢失数据。持久化技术主要用于MVC模型中的m...
    公子无礼阅读 1,678评论 0 4
  • 前言: 在程序开发中,数据层永远是程序的核心结构之一。对这些数据的加工处理是代码中能体现技术水平的一大模块,比如数...
    麦穗0615阅读 1,457评论 3 22
  • IOS数据持久化 数据的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据。在i...
    koula阅读 1,157评论 0 19
  • Title: iOS数据持久化 ##数据持久化概念 数据持久化就是将内存中的数据模型转换为存储模型,以及将存储模型...
    barrylyl阅读 932评论 0 3