您的位置:首页 > 产品设计 > UI/UE

iOS中 数据持久化 UI高级_17

2015-10-13 18:51 495 查看
数据持久化的本质就是把数据由内写到本地(硬盘中),在iOS指将数据写到沙盒文件夹下;

沙盒机制:指的就是采用沙盒文件夹的形式管理应用程序的本地文件,而且沙盒文件夹的名字是随机分配的,采用十六进制方法命名;

=======================关于沙盒目录==========================

沙盒内部构造:



测试沙盒:

属性:

@interface ViewController ()
@property (retain, nonatomic) IBOutlet UITextField *nameField;
@property (retain, nonatomic) IBOutlet UITextField *passwordField;
@property(nonatomic,retain)NSUserDefaults *user;
@end


//登录按钮

- (IBAction)handleLgin:(UIButton *)sender {
//取出输入框中的数据
NSString *name = self.nameField.text;
NSString *password = self.passwordField.text;
//取出用户偏好设置
NSString *pName =  [self.user valueForKey:@"name"];
NSString *pPassword = [self.user valueForKey:@"password"];
//当输入的内容和本地存储的信息相同时显示登录成功
if ([name isEqualToString:pName] && [password isEqualToString:pPassword]) {
NSLog(@"登陆成功");
}else{
NSLog(@"登录失败,请注册");
}
}


//注册按钮

- (IBAction)handleRegister:(UIButton *)sender {

NSString *name = self.nameField.text;
NSString *password = self.passwordField.text;
//当不输入内容的时候提前结束方法
if (name.length == 0 || password.length == 0) {
NSLog(@"账户名或者密码为空,注册失败!");
return;
}

//本地文件中设置用户名和用户密码
//设置用户名
[self.user setObject:name forKey:@"name"];
//设置用户密码
[self.user setObject:password forKey:@"password"];
//同步数据
[self.user synchronize];
NSLog(@"注册成功");

}
记得释放:

- (void)dealloc {
[_nameField release];
[_passwordField release];
self.user = nil;
[super dealloc];
}
测试结果:



————————————————————————



————————————————————————————

1.获取沙盒文件夹的路径

NSHomeDirectory() 沙盒文件的主目录,在这个文件夹下放着三个文件Document,Libralay,Tmp,其中Library 中还有两个文件Caches,Perference,系统帮我们创建五个文件存放在沙盒文件下,这五个是不能删除的

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


Documents: 存放一些比较重要的文件,文件大小比较小,这些都是可以有副本,此文件夹中不能有太多东西,否则在上传AppStore中会直接被拒,比如: 数据库

获取Documents 文件夹的路径

第一个参数:文件夹的名字 64行

第二个参数:搜索域,有优先级:users -->local -->network -->system

第三个参数:相对路径或者是绝对路径 YES绝对路径,NO代表相对路径

此方法最早是应用在MAC端开发的,对于PC 端可以有很多的用户,所以该方法的返回值是一个数组,但是现在这个方法应用在移动端(iOS端),而移动端用户只有一个,所以获取的路径也只有一个

NSString *documentsPath =   [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
NSLog(@"%@",documentsPath);


Library 资源库,存放的一些不太重要的文件,相对比较大,且其中有两个子文件

NSString *libraryPath =   [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)lastObject];
NSLog(@"%@",libraryPath);


Caches 存放一些缓存的文件,如网页缓存,图片缓存,视频缓存,视频缓存,应用中"清除缓存"功能,清理的就是这个文件夹里面的内容

//获取Caches路径

NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
NSLog(@"%@",cachesPath);


//Perferences 偏好设置,存放一些用户的信息

注意:路径是找不到的,只能通过NSUserDefaults 访问

NSUserDefaults *user = [NSUserDefaults standardUserDefaults];


//perferences 中存放的都是plist 文件,在第一次设置键值对的时候,会帮你创建plist文件,如果直接取值的时候,plist 文件是没有的

赋值和取值:

//    [user setBool:YES forKey:@"login"];
//取出BOOL值
//BOOL isLogin =  [user boolForKey:@"login"];
//    NSLog(@"%d",isLogin);


//NSUserDefaults 支持的数据类型:array,dictionary,string,data,number,bool,integer等

//NSUserDefaults 中一般存储数值类型的数据,不存放大型的数据

//模拟启动用户引导图

BOOL isFirstLogin = [user boolForKey:@"login"];
if (NO == isFirstLogin) {
NSLog(@"第一次启动");
[user setBool:YES forKey:@"login"];
[user synchronize];//立即同步
}else{
NSLog(@"不是第一次启动");
}


//Tem 存放临时文件 比如:压缩包 zip ,解压后就删除处理了

获取Tem的路径

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


NSFileManager 文件管理类,是一个文件管理工具,主要用于文件的的添加、删除、拷贝,继承自 NSObject

NSFileManager 也是一个单例类

NSFileManager *fileManger = [NSFileManager defaultManager];


=======================文件的创建==========================

NSFileManager常用操作一览表:



//在Document 文件下创建一个文件 av.text

1.获取Documents 路径

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


2.创建av.text 的路径

//    stringByAppendingFormat 拼接上什么就得到什么
//    stringByAppendingString  拼接上什么就得到什么
//    stringByAppendingPathExtension  拼接的内容前加一个点
//    stringByAppendingPathComponent  拼接的内容前加一个 /
NSString *avPath =   [documentsPath stringByAppendingPathComponent:@"av"];
NSLog(@"%@",avPath);


首先判断文件是否存在

<span style="color:#3333ff;">    if ([fileManger fileExistsAtPath:avPath]) {
NSLog(@"存在");
}else{
NSLog(@"不存在");
</span><span style="color:#cc0000;">  //创建 av.text文件
//第二个参数询问:如果路径中没有文件夹是否自动创建</span><span style="color:#3333ff;">
BOOL isSuccss = [fileManger createDirectoryAtPath:avPath withIntermediateDirectories:YES attributes:nil error:nil];
if (isSuccss) {
NSLog(@"创建成功");
}else{
NSLog(@"创建失败");
}
}</span>


=======================文件的删除==========================

//删除文件夹

1.先判断有没有要删的文件夹存在

if ([fileManger fileExistsAtPath:avPath]) {
//如果存在就删除
BOOL isSuccess = [fileManger removeItemAtPath:avPath error:nil];
NSLog(@"%@",isSuccess ? @"删除成功":@"删除失败");
}


=======================文件的拷贝==========================

//把NB.plist 拷贝到 AV 文件夹下

//NSBundle 应用程序包,我们从AppStore下载的应用就是这个包

//获取应用程序包的路径

//iOS8.0 之后,**.app 单独存放在一个文件内,**.app 这个文件只能读,不能写入,最终上传到AppStore 的包就是这个包

NSString *bundlePath = [[NSBundle mainBundle]bundlePath];
NSLog(@"%@",bundlePath);
//1.获取NB.plist 的路径
NSString *nbPath = [[NSBundle mainBundle]pathForResource:@"NB.plist" ofType:nil];
//2.制造移动到沙盒Documents 文件夹下AV文件夹下NB.plist
NSString *desPath = [avPath stringByAppendingPathComponent:@"NB.plist"];
//3.文件拷贝
if (![fileManger fileExistsAtPath:desPath]) {
//第一个参数:copy之前的路径
//第二个参数:要拷贝到的位置
BOOL isSucess = [fileManger copyItemAtPath:nbPath toPath:desPath error:nil];
NSLog(@"%@",isSucess ? @"拷贝成功":@"拷贝失败");
}


=======================文件的移动==========================

//从AV文件夹下,移动到Library文件夹下
//1.移动之前的路径
NSString *surcePath = desPath;
//2.移动之后的路径
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)lastObject];

NSString *toPath = [libraryPath stringByAppendingPathComponent:@"NB.plist"];
//移动
if (![fileManger fileExistsAtPath:toPath]) {
BOOL isSuccess = [fileManger moveItemAtPath:surcePath toPath:toPath error:nil];
NSLog(@"%@",isSuccess ? @"移动成功":@"移动失败");
}

//调用简单对象的写入和读取
[self simpleObjectWritwTpFileAndFromeFile];
//调用归档和反档
[self archiverAndArchiver];

}


=======================简单对象的写入和读取==========================

//简单对象指的是:NSString ,NSDictionary,NSData以及他们的子类

//注意:集合(NSArray,NSDictionary)的元素,必须是上面的四种基本数据类型,不能放复杂对象,才能直接进行文件的写入和读取;

字符串的写入与读取:

//1.字符串的写入
NSString *string = @"小韩哥真帅";
//2.在Documents 文件夹下创建一个文件"text.text"

NSString *textPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"text.text"];
//    NSLog(@"%@",textPath);

//3.字符串的写入
// 第一个参数:要写入的文件路径
// 第二个参数: YES提供多线程的安全防护,NO则不提供安全防护
// 第三个参数:编码的格式
BOOL isSuccess = [string writeToFile:textPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",isSuccess ? @"写入成功" :@"写入失败");

//4.字符串从文件中读取数据
//第一个参数:要读取的文件路径
NSString *contentString = [NSString stringWithContentsOfFile:textPath encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",contentString);


NSArray 的读取和写入:

//1.准备数组
NSArray *array = @[@"小韩哥",@"蔡国庆",@"周杰伦"];
//2.将数组写入到 caches 文件夹下 的array.text
NSString *arrayPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"array.text"];
//3.数组写入 数组写入后的文件是XML格式的
isSuccess = [array writeToFile:arrayPath atomically:YES];
NSLog(@"%@",isSuccess ? @"数组写入成功":@"数组写入失败");

//数组的读取
NSArray *contentArray = [NSArray arrayWithContentsOfFile:arrayPath];
NSLog(@"%@",contentArray);


NSDictionary 的写入和读取 写入之后变成xml格式:

//1.准备字典
NSDictionary *dic = @{@"男":@"小韩哥",@"明星":@"蔡国庆",@"国家主席":@"习大大"};
//2.tem 文件夹下创建一个Dictionary.text 文件
NSString *dictionaryPath = [NSTemporaryDirectory()stringByAppendingPathComponent:@"dictionary.text"];
//3.字典的写入
isSuccess = [dic writeToFile:dictionaryPath atomically:YES];
NSLog(@"%@",isSuccess ? @"字典写入成功":@"字典写入失败");

//4.字典的读取
NSDictionary *contentDic = [NSDictionary dictionaryWithContentsOfFile:dictionaryPath];
NSLog(@"%@",contentDic);


NSData 写入和读取:

NSString *dataString = @"我想对我身边人说,你该洗脚了";
//1.准备NSData 对象
NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
//2.在library 中写入 data.text 文件
NSString *dataPath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"data.text"];
//3.NSData 的写入
isSuccess = [data writeToFile:dataPath atomically:YES];
NSLog(@"%@",isSuccess ? @"NSData写入成功":@"NSData写入失败");

//4.NSData 的读取
NSData *contentData = [NSData dataWithContentsOfFile:dataPath];
//将二进制流转为字符串
NSString *newString = [[[NSString alloc]initWithData:contentData encoding:NSUTF8StringEncoding]autorelease];
NSLog(@"%@",newString);


=======================复杂对象的写入和读取==========================

复杂对象,就是Fundation 框架下不存在的数据类,也就是我们自己定义类,就叫复杂对象,复杂对象不能直接写入到文件,必须借助一些工具,NSKeyedArchiver(归档工具),读取时必须借助工具类NSKeyedUnarchiver(反归档工具)

归档和反档:

1.创建复杂对象Person

Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject<NSCoding>
//如果复杂对象想要完成归档和反归档,则这个对象必须遵循NSCoding协议
- (void)encodeWithCoder : (NSCoder *)aCoder;

@property(nonatomic,copy)NSString *name;//姓名
@property(nonatomic,copy)NSString *gender;//性别
@property(nonatomic,assign)NSInteger age;//年龄

- (id)initWithName : (NSString *)name gender : (NSString *)gender age : (NSInteger )age;
@end


Person.m

#import "Person.h"

@implementation Person
- (void)dealloc{
self.name = nil;
self.gender = nil;
[super dealloc];

}

- (id)initWithName : (NSString *)name gender : (NSString *)gender age : (NSInteger )age{
if (self = [super init]) {
self.name = name;
self.age = age;
self.gender = gender;

}
return self;
}
-(NSString *)description{
return [NSString stringWithFormat:@"%@-%@-%ld",_name,_gender,_age];
}
//归档的协议方法
- (void)encodeWithCoder : (NSCoder *)aCoder{
//不止这个对象要归档,它的属性要被归档,此时要对它的属性进行编码
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.gender forKey:@"gender"];
[aCoder encodeObject:@(self.age) forKey:@"age"];

}
//反归档的协议方法
- (id)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
//解码
self.name = [aDecoder decodeObjectForKey:@"name"];
self.gender = [aDecoder decodeObjectForKey:@"gender"];
self.age = [[aDecoder decodeObjectForKey:@"age"]integerValue];

}
return self;
}
@end
归档:

//1.创建复杂对象Person
Person *p1 = [[[Person alloc]initWithName:@"小韩哥" gender:@"男" age:20]autorelease];
//2.创建归档工具
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
//3.归档
//第一个参数:要被归档的对象
//第二个参数:给归档对象一个key值,作为 标识,方便反归档的时候把它找回来
[archiver encodeObject:p1 forKey:@"boyFriend"];
//4.完成归档
[archiver finishEncoding];
//5.释放
[archiver release];

//6.将归档后的数据文件
//将文件写入到沙盒文件夹下
NSString *personPath = [NSHomeDirectory() stringByAppendingPathComponent:@"person.text"];
//7.将转化的data数据写入到文件中
BOOL isSuccess = [data writeToFile:personPath atomically:YES];
NSLog(@"%@",isSuccess ? @"写入成功":@"写入失败");


反归档:

NSData *contentData = [NSData dataWithContentsOfFile:personPath];
//1.创建反归档工具
NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:contentData];
//2.读取文件(需要执行归档方法)
Person *p2 = [unArchiver decodeObjectForKey:@"boyFriend"];
NSLog(@"%@",p2);
//3.停止反归档
[unArchiver finishDecoding];
//4.释放
[unArchiver release];


=======================数组和复杂对象结合==========================

创建数组:

Person *p3 = [[Person alloc]initWithName:@"小美女" gender:@"女" age:21];
Person *p4 = [[Person alloc]initWithName:@"郭美美" gender:@"女" age:19];
NSArray *pArray = @[p3,p4];
[p3 release];
[p4 release];


//注意:复杂对象存入数组要想完成归档,那么存入的复杂对象必须遵循NSCoding协议

//使用归档把数组写入到文件

//1.创建归档工具
NSMutableData *aData = [NSMutableData data];
NSKeyedArchiver *nArchvier = [[NSKeyedArchiver alloc]initForWritingWithMutableData:aData];
//2.使用归档对象把数组归档
[nArchvier encodeObject:pArray forKey:@"array"];
//3.停止归档工具
[nArchvier finishEncoding];
//4.释放
[nArchvier release];


//文件写入到Documents 文件夹下,"array.tet"

NSString *arrayPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"array.text"];
isSuccess =  [aData writeToFile:arrayPath atomically:YES];
NSLog(@"%@",isSuccess ? @"复杂数组写入成功":@"复杂数组写入失败");


//复杂数组的读取

//复杂数组的读取
NSData *newData = [NSData dataWithContentsOfFile:arrayPath];
//1.创建反归档工具
NSKeyedUnarchiver *nUnarchvier = [[NSKeyedUnarchiver alloc]initForReadingWithData:newData];
//2.通过key值将对象反归档
NSArray *newArray = [nUnarchvier decodeObjectForKey:@"array"];
//3.停止反归档工具
[nUnarchvier finishDecoding];
//4.释放
[nUnarchvier release];
NSLog(@"%@ %@",newArray[0],newArray[1]);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: