数据存取

iOS应用数据存储的常用方式

XML属性列表(plist)归档

Preference(偏好设置)

NSKeyedArchiver归档(NSCoding)

SQLite3 

Core Data

 

计算机生成了可选文字:应 用 沙 盒 每 个 应 用 都 有 自 己 的 应 用 沙 盒 ( 应 用 沙 盒 就 是 应 用 的 文 件 夹 ) , 与 其 他 文 件 系 统 隔 离 。 应 用 必 须 待 在 自 己 的 沙 盒 里 , 其 他 应 用 不 能 访 问 该 沙 盒 应 用 沙 盒 的 文 件 系 统 目 录 , 如 下 图 所 示 ( 假 设 应 用 的 名 称 叫 Layer) 0 , Documents v = Library , = Caches 、 Preferences tmp 模 拟 器 应 用 沙 盒 的 根 路 径 在 : ( app 工 e 是 用 户 名 , 6 . 0 是 模 拟 器 版 本 ) /Users/apple/Library/App1ication Support/iPhone Simulator/ 6 、 0/Applications

 

注意:最常用的就是Documents,是有备份的

应用沙盒结构分析

应用程序包:(上图中的Layer)包含了所有的资源文件和可执行文件

Documents:保存应用运行时生成的需要持久化的数据iTunes同步设备时会备份该目录。例如,游戏应用可将游戏存档保存在该目录

 

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

 

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

 

Library/Preference:保存应用的所有偏好设置iOSSettings(设置)应用会在该目录中查找应用的设置信息。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];

 

tmpNSString*tmp = NSTemporaryDirectory();

Library/Caches(Documents类似的2种方法)

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

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

 

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

 

属性列表

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

如果对象是NSStringNSDictionaryNSArrayNSDataNSNumber等类型,就可以使用writeToFile:atomically:方法直接将对象写到属性列表文件中

 

属性列表-归档NSDictionary

将一个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];

 

计算机生成了可选文字:v Documents El Stu.plist e?xml version:" 1. r «!DOCTYPE pust PUBLIC "-//APPW/DTD PLIST Cpl ist edicts c string»27c/string» eke Fname" kep r inp c key.»phonec/ kep e/dict*

 

xcode打开属性文件

计算机生成了可选文字:000 stu.plist? No Selection Root age phone stu.plist Type Dictionary String String string Value (3 items) 27 15013141314

 

属性列表-恢复NSDictionary

读取属性列表,恢复NSDictionary对象

// 读取Documents/stu.plist的内容,实例化NSDictionary

NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];

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

NSLog(@"phone:%@", [dictobjectForKey:@"phone"]);

NSLog(@"age:%@", [dictobjectForKey:@"age"]);

打印信息如下

计算机生成了可选文字:name : phone: 15M3141314 age:27

 

计算机生成了可选文字:NSDictionary Wri teToFi1e : at dictiona stu . plist NSDicti ona ry i thContentsOEFi1e :

 

 

计算机生成了可选文字:• *Of-kb. NSÜserDeEau1ts *defaults NSUserDefau1ts standardÜserDeEau1tsJ defaults itcast" defaults setF10at:18 . Cf defaults setB001 : YES login"), Library Caches cn.itcast.preference.plist com.app e.Peop epic er.p ist pust PUBLIC "-//App1e//DTD cptist to_ log ine/ keys €t rue', g ke ize«/ kep crea reab ekepu s er name" keys estring»itcaste/st ring» «/dict*

 

读取上次保存的设置

NSUserDefaults *defaults = [NSUserDefaultsstandardUserDefaults];

NSString *username = [defaults stringForKey:@"username"];

float textSize = [defaults floatForKey:@"text_size"];

BOOL autoLogin = [defaults boolForKey:@"auto_login"];

 

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

[defaultssynchornize];

 

NSKeyedArchiver

如果对象是NSStringNSDictionaryNSArrayNSDataNSNumber等类型,可以直接用NSKeyedArchiver进行归档和恢复

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

NSCoding协议有2个方法:

encodeWithCoder:

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

initWithCoder:

每次从文件中恢复(解码)对象时,都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey方法解码实例变量

 

计算机生成了可选文字:NSKeyedÄrchiver-IJaHNSÄrray Documents / array . archive NSArray *array tNSArray arrayWithObjects: nil) • NSKeyedÄrchiver archiveRootObject: array toFi1e:pathJ • • IJ*JJUYJ v Documents array .archive NSArray * array NSÄrray archiveRoot CNSKeyedUnazchiver unarchiveObjectWithFi1e: path) ct: toFi1e : array unarchi . archive NSÄrra ectWi thFi1e :

 

 

NSKeyedArchiver-归档Person对象(Person.h

@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.nameforKey:@"name"];

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

    [encoder encodeFloat:self.heightforKey:@"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];

 

NSKeyedArchiver-归档对象的注意

如果父类也遵守了NSCoding协议,请注意:

应该在encodeWithCoder:方法中加上一句

[super encodeWithCode:encode];

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

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

self = [superinitWithCoder:decoder];

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

 

计算机生成了可选文字:NSData 使 用 ar 。 h 工 veR 。 。 乜 Obje 。 乜 : 乜 。 File : 方 法 可 以 将 一 个 对 象 直 接 写 入 到 一 个 文 件 中 , 但 有 时 候 可 能 想 将 多 个 对 象 写 入 到 同 一 个 文 件 中 , 那 么 就 要 使 用 NSDa 乜 a 来 进 行 归 档 对 象 NS Data 可 以 为 一 些 数 据 提 供 临 时 存 储 空 间 , 以 便 随 后 写 入 文 件 , 或 者 存 放 从 磁 盘 读 取 的 文 件 内 容 。 可 以 使 用 INSMutab1eData da 乜 a ] 创 建 可 变 数 据 空 间 encodeObjecE:forKey. 件 writeroFiIe : 靄 匕 omic 11v NSData dataWiEhConEentBOEFiIe : decodeObjecEForKey . encodeObj ect : forKey Object2 decodeObjecEForKey . 注 : 黑 色 箭 头 表 示 将 对 象 归 档 到 文 件 中 , 红 色 箭 头 表 示 从 文 件 中 恢 复 对 象

 

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

归档(编码)

// 新建一块可变数据区

NSMutableData *data = [NSMutableData data];

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

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

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

[archiver encodeObject:person1forKey:@"person1"];

[archiver encodeObject:person2forKey:@"person2"];

// 存档完毕(一定要调用这个方法)

[archiver finishEncoding];

// 将存档的数据写入文件

[data writeToFile:path atomically:YES];

 

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

恢复(解码)

// 从文件中读取数据

NSData *data = [NSData dataWithContentsOfFile:path];

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

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

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

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

// 恢复完毕

[unarchiver finishDecoding];

 

计算机生成了可选文字:NSData *data CNSKeyedÄrchiver archivedDataWithRootObj ect: person 1 ) / / Efidata, 4 Student *person2 CNSKeyedUnarchiver unarchiveObjectWithData : data) NSLog (g "person 1 : Ox%x" NSLog : Ox%x" person 1) ; person2) ; // person1:0x7177a60 // person2:0x7177cf0 unarchiveObjectWi EhData : NSData person2 archivedDaEaWithRootObject: personl

 

 

数据存储

# 2-数据存储

## 1.plist存储

1.plist存储,生成一个plist文件.

 

2.plist不是数组就是字典,plist存储就是用来存储字典或者数组.

 

注意:Plist不能存储自定义对象

 

3.获取应用沙盒中Caches文件路径

 

 

 directory:获取哪个文件夹

 domainMask:在哪个范围内搜索,NSUserDomainMask:表示在用户的手机上查找

 expandTilde:是否展开全路径 YES:表示展开全路径 NO:不会展开全路径,会把应用沙盒的路径用波浪号(~)代替

 

 获取到Caches文件夹路径

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

 

4.读取plist,之前是什么类型存储的,读取也是什么

 

## 2.偏好设置存储

 

 

 偏好设置存储:NSUserDefaults

 以字典的形式进行偏好设置,用法跟字典.

 偏好设置好处:  1.不需要关心文件名

              2.快速进行键值对存储

              3.直接存储基本数据类型

 

 

## 3.归档

1.NSKeyedArchiver专门用来做自定义对象归档

 

 

 什么时候调用:当一个对象要归档的时候就会调用这个方法归档

 作用:告诉苹果当前对象中哪些属性需要归档

- (void)encodeWithCoder:(NSCoder *)aCoder

{

    [aCoderencodeObject:_name forKey:@"name"];

    [aCoderencodeInt:_age forKey:@"age"];

}

 

 什么时候调用:当一个对象要解档的时候就会调用这个方法解档

 作用:告诉苹果当前对象中哪些属性需要解档

 initWithCoder什么时候调用:只要解析一个文件的时候就会调用

- (id)initWithCoder:(NSCoder *)aDecoder

{

#warning [super initWithCoder]

    if (self = [super init]) {

        解档

         注意一定要记得给成员属性赋值

       _name = [aDecoder decodeObjectForKey:@"name"];

       _age = [aDecoder decodeIntForKey:@"age"];

    }

    return self;

}

 

 

计算机生成了可选文字:SQLite3 s ite3 是 一 款 开 源 的 嵌 入 式 关 系 型 数 据 库 , 可 移 植 性 好 、 易 使 用 、 内 存 开 销 小 s ite3 是 无 类 型 的 , 意 味 着 你 可 以 保 存 任 何 类 型 的 数 据 到 任 意 表 的 任 意 字 段 中 。 比 如 下 列 的 创 表 语 句 是 合 法 的 create table t_person(name, age) , 为 了 保 证 可 读 性 , 建 议 还 是 把 字 段 类 型 加 上 : create table t_person(name text, age integer) SQ ite3 常 用 的 5 种 数 据 类 型 : text 、 integer 、 float 、 boolean 、 blob 在 i0S 中 使 用 so te3 , 首 先 要 添 加 库 文 件 libsqli 3 . dy 二 b 和 导 入 主 头 文 件 #import «sqlite3.lV ' unk Binary With Libraries 0 iter , 匚 」 OS 6 . 0 ulKit.framework eFoundation-framework | Corecraphics.framework

 

 

创建、打开、关闭数据库

创建或打开数据库

// path为:~/Documents/person.db

sqlite3 *db;

int result = sqlite3_open([pathUTF8String], &db); 

 

代码解析:

sqlite3_open()将根据文件路径打开数据库,如果不存在,则会创建一个新的数据库。如果result等于常量SQLITE_OK,则表示成功打开数据库

sqlite3 *db:一个打开的数据库实例

数据库文件的路径必须以C字符串(而非NSString)传入

 

关闭数据库:sqlite3_close(db);

 

执行不返回数据的SQL语句

执行创表语句

char *errorMsg;  // 用来存储错误信息

char *sql = "create table if not exists t_person(idinteger primary key autoincrement, name text, age integer);";

int result = sqlite3_exec(db,sql, NULL, NULL, &errorMsg);

 

代码解析:

sqlite3_exec()可以执行任何SQL语句,比如创表、更新、插入和删除操作。但是一般不用它执行查询语句,因为它不会返回查询到的数据

sqlite3_exec()还可以执行的语句:

开启事务:begintransaction;

回滚事务:rollback;

提交事务:commit;

 

带占位符插入数据

char *sql = "insert into t_person(name, age) values(?,?);";

sqlite3_stmt *stmt;

if (sqlite3_prepare_v2(db,sql, -1, &stmt, NULL) == SQLITE_OK) {

    sqlite3_bind_text(stmt, 1, "母鸡", -1, NULL);

    sqlite3_bind_int(stmt,2, 27);

}

if (sqlite3_step(stmt)!= SQLITE_DONE) {

    NSLog(@"插入数据错误");

}

sqlite3_finalize(stmt);

 

代码解析:

sqlite3_prepare_v2()返回值等于SQLITE_OK,说明SQL语句已经准备成功,没有语法问题

sqlite3_bind_text():大部分绑定函数都只有3个参数

1个参数是sqlite3_stmt*类型

2个参数指占位符的位置,第一个占位符的位置是1,不是0

3个参数指占位符要绑定的值

4个参数指在第3个参数中所传递数据的长度,对于C字符串,可以传递-1代替字符串的长度

5个参数是一个可选的函数回调,一般用于在语句执行后完成内存清理工作

sqlite_step():执行SQL语句,返回SQLITE_DONE代表成功执行完毕

sqlite_finalize():销毁sqlite3_stmt*对象

 

查询数据

char *sql = "select id,name,age from t_person;";

sqlite3_stmt *stmt;

if (sqlite3_prepare_v2(db,sql, -1, &stmt, NULL) == SQLITE_OK) {

    while (sqlite3_step(stmt)== SQLITE_ROW) {

        int _id = sqlite3_column_int(stmt, 0);

        char *_name = (char *)sqlite3_column_text(stmt, 1);

        NSString *name = [NSString stringWithUTF8String:_name];

        int _age = sqlite3_column_int(stmt, 2);

        NSLog(@"id=%i, name=%@,age=%i", _id, name, _age);

    }

}

sqlite3_finalize(stmt);

代码解析

sqlite3_step()返回SQLITE_ROW代表遍历到一条新记录

sqlite3_column_*()用于获取每个字段对应的值,2个参数是字段的索引,从0开始

 

计算机生成了可选文字:Core D core D 彐 七 a 框 架 提 供 了 对 象 一 关 系 映 射 〔 ORLX 的 功 能 , 即 能 够 将 OC 对 象 转 化 成 数 据 , 保 存 在 SOLite3 数 据 库 文 件 中 , 也 能 够 将 保 存 在 数 据 库 中 的 数 据 还 原 成 oc 对 象 。 在 此 数 据 操 作 期 间 , 不 需 要 缤 写 任 何 SOL 句 。 使 用 此 功 能 , 要 添 加 CoreData framework 和 导 入 主 头 文 件 GoreData/CoreData.LV» 关 系 模 型 person Core id name age 2 3 Data 对 象 模 型 "NJ' age age E"JJ'

 

 

计算机生成了可选文字:模 型 文 件 在 core Data , 需 要 进 行 映 射 的 对 象 称 为 实 体 ( en 亡 i 亡 y 汽 而 且 需 要 使 用 c 。 re Dat a 的 模 型 文 件 来 描 述 应 用 的 所 有 实 体 和 实 体 属 性 这 里 以 person 和 card( 身 份 证 ) 2 个 实 体 为 例 子 , 先 看 看 实 体 属 性 和 之 间 的 关 联 关 系 ESOn age 中 有 个 c d 属 性 , card 中 有 个 Person 属 性 person 属 于 一 对 一 双 向 关 联

 

计算机生成了可选文字:Choose a template for your new file: ios Cocoa Touch C and Data Model Other osx Mapping Model Products Outline Style Add Entity

 

计算机生成了可选文字:Type Integer 16 String A Type String Name age Propertie CI Transient Optional Indexed Attribute Type Integer 16 Validation Minimum Maximum o : Default ENTITIES FETCH REQUESTS CONFIGURATIONS Default V Attributes Attribute ENTITIES V Attributes card Attribute Person FETCH REQUESTS CONFIGURATIONS

 

计算机生成了可选文字:Æ?erson ENTITIES a card FETCH REQUESTS CONFIGURATIONS fault Relationship Name card Destination Card Inverse Optional Plural LI To-Many Relationship V Attributes V Relationships Integer 16 Stri ng Destination Card Type String Destination person Count L : Minimum ÆCa rd s on ENTITIES Person FETCH REQUESTS CONFIGURATIONS Default V Attributes Relationships person Inverse

 

 

计算机生成了可选文字:NSManagedObj ect • • NSManagedCbj ionaryXim, • set Value : forKey: ( • valueForKey: Entity Name Person Class NSVanagedObjee_t Abstract Entity Pa rent Entity

 

 

计算机生成了可选文字:Core NSManagedObj ec tCon text (CRUD) . persistent StoreCocrdinatcr NS PersistentStoreCoordinator : ( Eti11SQLi . mana ec tMcde1 NSManagedOb j ec tMode1 R*core . entities NSEntityDescripti . name — NSEntityDescripti .nane — e" Person"

 

搭建CoreData上下文环境

从应用程序包中加载模型文件

NSManagedObjectModel*model = [NSManagedObjectModel mergedModelFromBundles:nil];

传入模型,初始化NSPersistentStoreCoordinator

NSPersistentStoreCoordinator*psc = [[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]autorelease];

构建SQLite文件路径

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

NSURL *url =[NSURL fileURLWithPath:[docsstringByAppendingPathComponent:@"person.data"]];

 

搭建CoreData上下文环境

添加持久化存储库,这里使用SQLite作为存储库

NSError *error = nil;

NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nilURL:url options:nil error:&error];

if (store == nil) { // 直接抛异常

    [NSException raise:@"添加数据库错误" format:@"%@", [errorlocalizedDescription]];

}

初始化上下文,设置persistentStoreCoordinator属性

NSManagedObjectContext*context = [[NSManagedObjectContext alloc] init];

context.persistentStoreCoordinator = psc;

// 用完之后,还是要[context release];

 

添加数据

传入上下文,创建一个Person实体对象

NSManagedObject *person= [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];

设置简单属性

[person setValue:@"MJ" forKey:@"name"];

[person setValue:[NSNumber numberWithInt:27]forKey:@"age"];

传入上下文,创建一个Card实体对象

NSManagedObject *card =[NSEntityDescription insertNewObjectForEntityForName:@"Card" inManagedObjectContext:context];

[card setValue:@"4414241933432"forKey:@"no"];

设置PersonCard之间的关联关系

[personsetValue:card forKey:@"card"];

 

利用上下文对象,将数据同步到持久化存储库

NSError *error = nil;

BOOL success = [contextsave:&error];

if (!success) {

    [NSException raise:@"访问数据库错误"format:@"%@", [error localizedDescription]];

}

// 如果是想做更新操作:只要在更改了实体对象的属性后调用[contextsave:&error],就能将更改的数据同步到数据库

 

查询数据

初始化一个查询请求

NSFetchRequest *request= [[[NSFetchRequest alloc] init]autorelease];

设置要查询的实体

NSEntityDescription*desc = [NSEntityDescription entityForName:@"Person"inManagedObjectContext:context];

设置排序(按照age降序)

NSSortDescriptor *sort= [NSSortDescriptor sortDescriptorWithKey:@"age"ascending:NO];

request.sortDescriptors = [NSArray arrayWithObject:sort];

设置条件过滤(name like '%Itcast-1%')

NSPredicate *predicate= [NSPredicate predicateWithFormat:@"namelike %@", @"*Itcast-1*"];

request.predicate= predicate;

 

执行请求

NSError *error = nil;

NSArray *objs = [context executeFetchRequest:requesterror:&error];

if (error) {

    [NSException raise:@"查询错误"format:@"%@", [error localizedDescription]];

}

遍历数据

for (NSManagedObject*obj in objs) {

    NSLog(@"name=%@", [obj valueForKey:@"name"]

}

 

删除数据

传入需要删除的实体对象

[context deleteObject:managedObject];

将结果同步到数据库

NSError *error = nil;

[context save:&error];

if (error) {

    [NSException raise:@"删除错误"format:@"%@", [error localizedDescription]];

}

 

计算机生成了可选文字:FCore Product Run Test Profile Analyze Archive Build For Perform Action Build Clean Stop Generate Output Debug Debug Workflow Attach to Process Edit Scheme... New Scheme. Manage Schemes De Sti nation Breakpo ntS Build I target Test De bug profile data-app Release Ana I yze De bug Arch Release Argument S -com.apple.CoreData.SQLDebug t Variables Val ue Expand Variables Based On data Option S settings like

 

Core Data的延迟加载

Core Data不会根据实体中的关联关系立即获取相应的关联对象

比如通过Core Data取出Person实体时,并不会立即查询相关联的Card实体;当应用真的需要使用Card时,才会查询数据库,加载Card实体的信息

 

计算机生成了可选文字:创 建 s ged0bje 。 t 的 子 类 默 认 情 况 下 , 利 用 c e Data 取 出 的 实 体 都 是 NSManagedObject 类 型 的 , 能 够 利 用 键 一 值 对 来 存 取 数 据 · 但 是 一 般 情 况 下 , 实 体 在 存 取 数 据 的 基 础 上 , 有 时 还 需 要 添 加 一 些 业 务 方 法 来 完 成 一 些 其 他 任 务 , 那 么 就 必 须 创 建 NSManagedOb3ect 的 子 类 〔 0 [ Touch 〔 and C++ Data Model Other 〔 0 [ Mapping Model NSManagedObject

 

计算机生成了可选文字:Select the data models with entities you Model Select the entities you would like to manage Person Model.xcdatamodeld h Personh m Person.m G' Card.h Card. m Framewo s

 

计算机生成了可选文字:Person. h — Person. m lass Card; @interface Person : NSManagedObject roperty (nonatomic, retain) NSNumber * age; roperty (nonatomic, retain) NSStrin * name; roperty (nonatomic, retain) Card *card; end Card. h — Card. m glass Person; einterface Card : NSManagedObject @property ( nonatomic, retain) NSStrin * n @property (nonatomic, retain) Person *person; end @implementation Person @dynamic age; @dynamic name; @dynamic card; @end Qimplementation Card @dynamic no; @dynamic person; @end

 

 

创建NSManagedObject的子类

那么生成一个Person实体对象就应该这样写

Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person"inManagedObjectContext:context];

person.name = @"MJ";

person.age = [NSNumber numberWithInt:27];

 

Card *card = [NSEntityDescription insertNewObjectForEntityForName:@”Card"inManagedObjectContext:context];

card.no = @”4414245465656";

person.card =card;

 

************************笔记*************************

*****************************************************

 

.数据存储(数据持久化)

1> 介绍iOS数据存储的5种方式

2> 介绍应用沙盒(应用程序的文件夹)

如何找到应用沙盒的路径?首先需要显示隐藏文件。

点击前往->个人->资源库->ApplicationSupport->iPhone Simulator->7.1->里面全是应用沙盒

3> 应用沙盒怎么多文件夹保存,在哪个文件夹。介绍沙盒里的每一个文件夹。

 

.plist存储

把一些系统自带的OC对象生成pilst文件存储起来。

1> 了解数据存储:数据存储一般有两个操作,一个存,一个取。拖两个按钮,一个用来存,一个用来取

2>plist存储原理:

只要有writeToFile的对象,就能进行plist存储,调用writeToFile就能自动生成plist格式的文件。

一般常用的Foundation对象都有这个方法,数组,字典,字符串等

3> 如何写入到沙盒,需要获取沙盒路径。

获取Documents路径

拼接文件名,因为数据是写入到文件中,不是写入到文件夹中。路径之间通过/分开的,为了避免自己写/,会用stringByAppendingPathCompent,自动在文件夹与文件之间添加/

4> 如何读取,存储是什么类型存储,读取出来也是什么类型,直接用存储的类型,解析文件就好,用ContentsOfFile解析。

5> 注意plist存储,不能存储自定义对象,会失败的。

 

 偏好设置

1> 什么是偏好设置存储:就是保存一些基本的信息,账号,密码,状态。

2> 偏好设置原理:不需要关心文件名,直接通过NSUserDefaults操作,默认就存到偏好设置里面了。

通过NSUserDefaults就能直接访问软件的偏好设置(Library/Preferences)

3> 怎么利用偏好设置存储?利用NSUserDefaults调用setObject:forKey存储。

偏好设置底层实现原理:底层其实就是利用一个字典,存储一些键值对。

偏好设置好处:能快速存储一些键值对,如果用字典去存储,还需要获取文件名比较麻烦。

偏好设置坏处:不能及时存储,需要做同步操作,把内存中的数据同步到硬盘上。

4> 怎么利用偏好设置读取?和字典一样,根据刚刚存储的Key读取。

 

自定义对象归档(归档:数据存储)

1> 自定义对象如何归档:用NSKeyedArchiver,调用archiveRootObject:toFile:方法,需要传一个对象,自定义一个对象,传进去。

•  会报错,说对象没有encodeWithCoder方法,说明归档的时候默认会调用这个方法,去实现这个方法。

默认打不出encodeWithCoder,必须遵守NSCoding协议才能实现这个方法。

•encodeWithCoder什么时候调用:对象归档时候调用

•encodeWithCoder作用:告诉系统对象里的哪些属性需要归档,怎么去归档,根据一个key去归档,目的就是以后取的时候,也根据这个key去取数据。

2> 自定义对象如何解档:NSKeyedUnarchiver,调用unarchiveObjectWithFile方法,需要传一个文件名。

会报错,说对象没有initWithCoder方法,说明解档的时候默认会调用这个方法,去实现这个方法。

•initWithCoder什么时候调用:对象解档时候调用

•initWithCoder作用:告诉系统对象里的哪些属性需要解档,怎么去解档,根据之前存储的key去解档

•initWithCoder是一个初始化方法,需要先初始化父类的,但是不能调用[super initWithCoder:],因为父类NSObject没有遵守NSCoding协议。

3>initWithCoder什么时候需要调用[super initWithCoder:]

•initWithCoder原理:只要解析文件就会调用,xib,storyboard都是文件,因此只要解析这两个文件,就会调用initWithCoder

因此如果在storyboard使用自定义view,重写initWithCoder方法,一定要调用[super initWithCoder:],因为只有系统才知道怎么解析storyboard,如果没有调用,就解析不了这个文件。

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值