IOS之数据持久化.docx
- 文档编号:27690362
- 上传时间:2023-07-04
- 格式:DOCX
- 页数:20
- 大小:224.32KB
IOS之数据持久化.docx
《IOS之数据持久化.docx》由会员分享,可在线阅读,更多相关《IOS之数据持久化.docx(20页珍藏版)》请在冰豆网上搜索。
IOS之数据持久化
IOS之数据持久化
9.1数据持久化概述
9.2iOS应用程序目录结构
9.3读写属性列表
9.4对象归档
9.5访问SQLite
9.1数据持久化概述
iOS中可以有四种持久化数据的方式:
属性列表、对象归档、SQLite3和CoreData
9.2iOS应用程序目录结构
iOS应用程序运行在Macos模拟器时候,有一下临时目录模拟器3.1.3为例子:
/Users/tony/Library/ApplicationSupport/iPhoneSimulator/3.1.3/Applications
IOS应用程序采用沙盒原理设计,ios每个应用程序都有自己的3个目录(Document,Library,tmp),互相之间不能访问。
Documents存放应用程序的数据。
Library目录下面还有Preferences和Caches目录,Preferences目录存放应用程序的使用偏好,Caches目录与Documents很相似可以存放应用程序的数据。
tmp目录供应用程序存储临时文件。
9.3读写属性列表
读取Documents目录下文件
可以获得应用程序的Documents文件夹。
NSArray*myPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString*myDocPath=[myPathsobjectAtIndex:
0];
获取文件的完整路径。
-(NSString*)filePath:
(NSString*)fileName{
NSArray*myPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString*myDocPath=[myPathsobjectAtIndex:
0];
NSString*filePath=[myDocPathstringByAppendingPathComponent:
fileName];
returnfilePath;
}
获取tmp目录
获取应用程序的tmp目录要比获取Documents目录容易的多。
使用函数NSTemporaryDirectory()可以获得tmp目录路径。
NSString*tempPath=NSTemporaryDirectory();
获取文件的完整路径。
NSString*tempFile=[tempPathstringByAppendingPathComponent:
@"properties.plist"];
属性列表文件实例:
PropertesList
PropertesListViewController.h
#import"Student.h"
@interfaceViewController:
UIViewController
@property(retain,nonatomic)IBOutletUITextField*studentNo;
@property(retain,nonatomic)IBOutletUITextField*studentName;
@property(retain,nonatomic)IBOutletUITextField*studentClass;
-(IBAction)save:
(id)sender;
-(IBAction)load:
(id)sender;
-(IBAction)endEditing:
(id)sender;
-(IBAction)saveToArchiver:
(id)sender;
-(IBAction)loadFromArchiver:
(id)sender;
-(NSString*)filePath:
(NSString*)fileName;
@end
PropertesListViewController.m
@synthesizestudentNo;
@synthesizestudentName;
@synthesizestudentClass;
-(NSString*)filePath:
(NSString*)fileName{
NSArray*myPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString*myDocPath=[myPathsobjectAtIndex:
0];
NSString*filePath=[myDocPathstringByAppendingPathComponent:
fileName];
returnfilePath;
}
-(IBAction)save:
(id)sender{
NSString*fileName=[selffilePath:
@"properties.plist"];
NSLog(fileName);
NSMutableArray*data=[[NSMutableArrayalloc]init];
[dataaddObject:
studentNo.text];
[dataaddObject:
studentName.text];
[dataaddObject:
studentClass.text];
[datawriteToFile:
fileNameatomically:
YES];
}
-(IBAction)load:
(id)sender{
NSString*fileName=[selffilePath:
@"properties.plist"];
if([[NSFileManagerdefaultManager]fileExistsAtPath:
fileName]){
NSArray*data=[[NSArrayalloc]initWithContentsOfFile:
fileName];
studentNo.text=[dataobjectAtIndex:
0];
studentName.text=[dataobjectAtIndex:
1];
studentClass.text=[dataobjectAtIndex:
2];
[datarelease];
}
}
-(IBAction)endEditing:
(id)sender{
[senderresignFirstResponder];
}
9.4对象归档
对象归档实例:
Encoding
对象归档
“归档”是值另一种形式的序列化,对模型对象进行归档的技术可以轻松将复杂的对象写入文件,然后再从中读取它们,只要在类中实现的每个属性都是基本数据类型(如int或float)或都是符合NSCoding协议的某个类的实例,你就可以对你的对象进行完整归档。
实现NSCoding协议
NSCoding协议声明了两个方法:
-(void)encodeWithCoder:
(NSCoder*)aCoder,是将对象写入到文件中。
-(id)initWithCoder:
(NSCoder*)aDecoder,是将文件中数据读入到对象中。
实现NSCopying协议
NSCopying协议声明了一个方法:
-(id)copyWithZone:
(NSZone*)zone,是将对象复制方法。
Student.h
@interfaceStudent:
NSObject
@property(retain,nonatomic)NSString*studentNo;
@property(retain,nonatomic)NSString*studentName;
@property(retain,nonatomic)NSString*studentClass;
@end
Student.m
#import"Student.h"
@implementationStudent
@synthesizestudentNo=_studentNo;
@synthesizestudentName=_studentName;
@synthesizestudentClass=_studentClass;
#pragmamarkNSCopying
-(id)copyWithZone:
(NSZone*)zone{
Student*copy=[[[selfclass]allocWithZone:
zone]init];
copy.studentNo=[_studentNocopyWithZone:
zone];
copy.studentName=[_studentNamecopyWithZone:
zone];
copy.studentClass=[_studentClasscopyWithZone:
zone];
returncopy;
}
#pragmamarkNSCoding
-(void)encodeWithCoder:
(NSCoder*)aCoder{
[aCoderencodeObject:
_studentNoforKey:
@"studentNo"];
[aCoderencodeObject:
_studentNameforKey:
@"studentName"];
[aCoderencodeObject:
_studentClassforKey:
@"studentClass"];
}
-(id)initWithCoder:
(NSCoder*)aDecoder{
_studentNo=[aDecoderdecodeObjectForKey:
@"studentNo"];
_studentName=[aDecoderdecodeObjectForKey:
@"studentName"];
_studentClass=[aDecoderdecodeObjectForKey:
@"studentClass"];
returnself;
}
-(NSString*)description{
return[[[NSStringalloc]initWithFormat:
@"no:
%@name:
%@class:
%@",_studentNo,_studentName,_studentClass]autorelease];
}
-(void)dealloc{
[_studentNamerelease];
[_studentClassrelease];
[_studentNorelease];
[superdealloc];
}
@end
EncodingViewController.h
详细见上。
EncodingViewController.m
-(IBAction)saveToArchiver:
(id)sender{
NSString*fileName=[selffilePath:
@"student.archiver"];
NSMutableData*data=[NSMutableDatadata];
NSKeyedArchiver*archiver=[[NSKeyedArchiveralloc]initForWritingWithMutableData:
data];
Student*student=[[Studentalloc]init];
student.studentNo=studentNo.text;
student.studentName=studentName.text;
student.studentClass=studentClass.text;
[archiverencodeObject:
studentforKey:
@"myStudent"];
[archiverfinishEncoding];
[datawriteToFile:
fileNameatomically:
YES];
[archiverrelease];
[studentrelease];
}
NSMutableData*theData=[NSMutableDatadata];用于包含编码的数据。
NSKeyedArchiver*archiver=[[NSKeyedArchiveralloc]initForWritingWithMutableData:
theData];创建NSKeyedArchiver实例,用于将对象归档到此theData实例中。
[archiverencodeObject:
studentforKey:
@"mystudent"];使用“键-值”对编码来对希望包含在归档中的对象进行归档。
[theDatawriteToFile:
filenameatomically:
YES];写入数据到归档文件。
EncodingViewController.m
-(IBAction)loadFromArchiver:
(id)sender{
NSString*fileName=[selffilePath:
@"student.archiver"];
NSData*data=[NSDatadataWithContentsOfFile:
fileName];
if([datalength]>0){
NSKeyedUnarchiver*unArchiver=[[NSKeyedUnarchiveralloc]initForReadingWithData:
data];
Student*student=[unArchiverdecodeObjectForKey:
@"myStudent"];
studentNo.text=student.studentNo;
studentName.text=student.studentName;
studentClass.text=student.studentClass;
[unArchiverfinishDecoding];
[unArchiverrelease];
}
}
NSData*theData=[NSDatadataWithContentsOfFile:
filename];从归档文件中获得NSData实例。
NSKeyedUnarchiver*archiver=[[NSKeyedUnarchiveralloc]initForReadingWithData:
theData];
创建一个NSKeyedUnarchiver实例对数据进行解码。
Student*student=[archiverdecodeObjectForKey:
@"mystudent"];
使用与归档编码使用相同的键对象进行解码。
9.5访问SQLite
SQLite数据库
SQLite是一个开源的嵌入式关系数据库,它在2000年由D.RichardHipp发布,它的减少应用程序管理数据的开销,SQLite可移植性好,很容易使用,很小,高效而且可靠。
SQLite嵌入到使用它的应用程序中,它们共用相同的进程空间,而不是单独的一个进程。
从外部看,它并不像一个RDBMS,但在进程内部,它却是完整的,自包含的数据库引擎。
嵌入式数据库的一大好处就是在你的程序内部不需要网络配置,也不需要管理。
因为客户端和服务器在同一进程空间运行。
SQLite的数据库权限只依赖于文件系统,没有用户帐户的概念。
SQLite有数据库级锁定,没有网络服务器。
它需要的内存,其它开销很小,适合用于嵌入式设备。
你需要做的仅仅是把它正确的编译到你的程序。
SQLite数据类型
SQLite是无类型的,这意味着你可以保存任何类型的数据到你所想要保存的任何表的任何列中,无
论这列声明的数据类型是什么,对于SQLite来说对字段不指定类型是完全有效的,如:
CreateTableex1(a,b,c);
SQLite允许忽略数据类型,但是仍然建议在你的CreateTable语句中指定数据类型,因为数据类型对于你和其他的程序员交流,或者你准备换掉你的数据库引擎。
SQLite支持常见的数据类型,如:
在iOS中使用SQLite3
为了能够在iOS中使用SQLite3需要是将libsqlite3.dylib类库添加到Xcode工程中,在工程的Frameworks(框架)文件夹右键添加存在Frameworks
或者导航到/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator
实例:
StudentSQLite3
StudentSQLite3ViewController.h
#import"sqlite3.h"
#defineDATA_FILE@"data.sqlite3"
#defineTABLE_NAME@"student"
#defineFIELDS_NAME_SID@"studentId"
#defineFIELDS_NAME_SNAME@"studentName"
#defineFIELDS_NAME_SCLASS@"studentClass"
@interfaceViewController:
UIViewController{
sqlite3*db;
}
@property(retain,nonatomic)IBOutletUITextField*studentId;
@property(retain,nonatomic)IBOutletUITextField*studentName;
@property(retain,nonatomic)IBOutletUITextField*studentClass;
-(IBAction)saveFromSqlite:
(id)sender;
-(IBAction)loadFromSqlite:
(id)sender;
-(NSString*)dataFile;
-(IBAction)textFieldDoneEditing:
(id)sender;
@end
StudentSQLite3ViewController.m
@synthesizestudentId;
@synthesizestudentName;
@synthesizestudentClass;
-(NSString*)dataFile{
NSArray*myPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString*myDocPath=[myPathsobjectAtIndex:
0];
NSString*fileName=[myDocPathstringByAppendingFormat:
DATA_FILE];
returnfileName;
}
无参数SQLite3处理过程
1、打开数据库sqlite3_open。
2、创建数据库表和执行SQL语句sqlite3_exec。
3、释放资源sqlite3_close。
创建数据库
-(void)viewDidLoad{
[superviewDidLoad];
NSString*fileName=[selfdataFile];
NSLog(@"%@",fileName);
if(sqlite3_open([fileNameUTF8String],&db)!
=SQLITE_OK){
sqlite3_close(db);
NSAssert(NO,@"OPENSQLITEDATABASEERROR!
");
}else{
char*error;
NSString*createSQL=[NSStringstringWithFormat:
@"CREATETABLEIFNOTEXISTS%@(%@TEXTPRIMARYKEY,%@TEXT,%@%TEXT);",
TABLE_NAME,FIELDS_NAME_SID,FIELDS_NAME_SNAME,FIELDS_NAME_SCLASS];
if(sqlite3_exec(db,[createSQLUTF8String],NULL,NULL,&error)){
sqlite3_close(db);
NSAssert1(NO,@"CREATETABLEERROR",error);
}else{
sqlite3_close(db);
}
}
}
sqlite3_open([[selfdataFilePath]UTF8String],&db)!
=SQLITE_OKsqlite3_open打开数据库,注意:
在sqlite3中的函数都是使用C字符串[selfdataFilePath]UTF8String]是将NSString字符串转换为C字符串,&db是sqlite3指针(*db)的地址。
该函数sqlite3_open返回SQLITE_OK打开成功。
sqlite3_exec(db,[tablesqlUTF8String],NULL,NULL,&err)!
=SQLITE_OK
sqlite3_exec是执行任何不带返回值sql语句,第2个参数是要执行的sql语句,第3个参数是要回调函数,第4个参数是要回调函数的参数,第5个参数是执行出错的字符串。
sqlite3_close(db);是关闭数据库。
NSAssert是断言函数,当断言失败时候打印信息。
NSAssert1是带有一个参数的NSAssert函数,此外还有NSAssert2等函数。
有参数的SQLite3处理过程
1、打开数据库sqlite3_open。
2、预处理SQL语句sqlite3_prepare_v2。
3、绑定参数sqlite3_bind_text。
4、执行语句sqlite3_s
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- IOS 数据 持久