phone开发基础教程》第十一章 基本数据持久

phone开发基础教程》第十一章 基本数据持久,第1张

概述以前我们也用到过读取数据,但是没有一个应用程序是将其数据永久性存储,也就是在应用重启,机器重启后数据不会丢失,和上一次最后的数据一致。这章一共定义了三种保持数据的方法,第一种:实用属性列表,第二种:对象归档,第三种:使用Iphone的嵌入式数据库(SQLite3)   给予Iphone应用程序沙盒原理,我们保持的数据都是保存在相对应的应用程序的Document文件夹。既然我们把数据放在每一个应用的

以前我们也用到过读取数据,但是没有一个应用程序是将其数据永久性存储,也就是在应用重启,机器重启后数据不会丢失,和上一次最后的数据一致。这章一共定义了三种保持数据的方法,第一种:实用属性列表,第二种:对象归档,第三种:使用Iphone的嵌入式数据库(sqlite3)

给予Iphone应用程序沙盒原理,我们保持的数据都是保存在相对应的应用程序的document文件夹。既然我们把数据放在每一个应用的document文件夹中,呢我我们怎么得到相应的路径呢,其实也不是很难。下面是检索文档目录路径的代码:

NSArray *paths = NSSearchPathForDirectorIEsInDomains(NSdocumentDirectory,NSUserdomainMask,YES);

Nsstring *documentDirectory = [paths objectAtIndex:0];常量NSdocumentDirectory表面我们正在查找的document目录路径,常量NSUserDomainmask表明我们希望将搜索限制于我们应用程序的沙盒中。这样我们就可以得到该数组的第一值,也仅此一值,因为每一个应用程序只有一个document文件夹。我们得到了document的路径,然后和文件名相连接不就是一个完整的路径了吗,这用到了stringByAppendingPathComponent方法:

Nsstring *filepath = [documentDirectory stringbyAppendingPathComponent:@"filename.xxx"];其中filename.xxx为要命名的文件。

在每一个应用程序中还对应一个temp文件夹,我们怎么获取这个文件夹的路径呢,也比较简单:

Nsstring *tempPath = NstemporaryDirectory();

Nsstring *filePath = [tempPath stringByAppendingPathComponent:@"filename.xxx"];

下面我们来创建该项目:

第一个实用属性列表文件,打开Xcode,创建新项目,选择VIEw-Based Application即可,我创建项目名称是IP_11persistence。打开IP_11persistenceVIEwController.h,首先定义一个常量用来串联document。

#define kfilename @"data.pList"

然后定义四个输出口,用来输入和显示数据。

IBOutlet UITextFIEld *show1;
IBOutlet UITextFIEld *show2;
IBOutlet UITextFIEld *show3;
IBOutlet UITextFIEld *show4;

定义两个方法:

-(Nsstring *)datafilePath;//用来返回数据文件的完整路径名
-(voID)applicationWillTerminate:(NSNotification *)notification;//应用程序在退出时调用,将数据保存到数据列表

然后打开IP_11persistenceVIEwController.m

添加下面这三个方法:

-(Nsstring *)datafilePath//用来返回数据文件的完整路径名
{
NSArray *path = NSSearchPathForDirectorIEsInDomains(NSdocumentDirectory,NSUserDomainMask,YES);
Nsstring *paths = [path objectAtIndex:0];
return [paths stringByAppendingPathComponent:kfilename];


}

-(voID)applicationWillTerminate:(NSNotification *)notification//应用程序在退出时调用,将数据保存到数据列表
{
NSMutableArray *array = [[NSMutableArray alloc]init];
[array addobject:show1.text];
[array addobject:show2.text];
[array addobject:show3.text];
[array addobject:show4.text];
[array writetofile:[self datafilePath] atomically:YES];
[array release];
}

-(voID)vIEwDIDLoad
{
Nsstring *filePath = [self datafilePath];//得到文件路径
if([[NSfileManager defaultManager] fileExistsAtPath:filePath])//如果该文件存在就加载
{
NSArray *array = [[NSArray alloc] initWithContentsOffile:filePath];
show1.text = [array objectAtIndex:0];
show2.text = [array objectAtIndex:1];
show3.text = [array objectAtIndex:2];
show4.text = [array objectAtIndex:3];
[array release];
}

基本数据持久性" src="http://img.jb51.cc/vcimg/static/loading.png" alt="《Iphone开发基础教程》第十一章

基本数据持久性" width="279" height="442" align="right" src="http://static15.photo.sina.com.cn/bmiddle/60b45f23g711201e1746e&690">


UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addobserver:self selector:@selector(applicationWillTerminate:)
name:UIApplicationWillTerminateNotification
object:app];
[super vIEwDIDLoad];
}

代码已经搞定,下面点开Resources文件夹,打开IP_11persistenceVIEwController.xib,向里面拖入4个UITextFIEld控件,勾掉每一个控件上的Clear When Editing Begin,这样就不是每次选中文本框的时候会自动消失里面的内容了。关联四个控件即可。(在实际的例子当中我添加两个方法,一个是在点击回车时,软键盘自动消失,一个是在点击背景是软键盘自动消失,这两个方法在第四章中有详细的讲解,可以去参考)。build and go运行,这是你输入内容,关闭应用程序,然后在打开,你会发现你刚才输入的内容仍然存在,下面开始第二种方法,使用对象归档的方法。

创建一个新的项目,我的项目名是:IP_11persistence2。创建好以后,在Classes文件夹上点右键创建一个新的类,选择NSObject subclass模板。名称为fourlines。打开fourlines.h,向里面添加四个常量和四个输出口:

#define kFIEld1Key @"show1"
#define kFIEld2Key @"show2"
#define kFIEld3Key @"show3"
#define kFIEld4Key @"show4"

Nsstring *show1;
Nsstring *show2;
Nsstring *show3;
Nsstring *show4;

打开fourlines.m文件,修改代码:

-(voID)encodeWithCoder:(NSCoder *)encoder //对所有的属性进行编码
{
[encoder encodeObject:show1 forKey:kFIEld1Key];
[encoder encodeObject:show2 forKey:kFIEld2Key];
[encoder encodeObject:show3 forKey:kFIEld3Key];
[encoder encodeObject:show4 forKey:kFIEld4Key];
}

-(ID)initWithCoder:(NSCoder *)decoder//使用相同的4格键值对这些属性进行解码
{
if(self == [super init])
{
self.show1 = [decoder decodeObjectForKey:kFIEld1Key];
self.show2 = [decoder decodeObjectForKey:kFIEld2Key];
self.show3 = [decoder decodeObjectForKey:kFIEld3Key];
self.show4 = [decoder decodeObjectForKey:kFIEld4Key];
}
return self;
}

-(ID)copyWithZone:(NSZone *)zone//创建一个新的fourline对象,并将所有4格字符串复制到其中
{
fourlines *copy = [[[self class] allocWithZone:zone] init];
show1 = [self.show1 copy];
show2 = [self.show2 copy];
show3 = [self.show3 copy];
show4 = [self.show4 copy];
return copy;
}

然后打开IP_11persistence2VIEwController.h,里面声明四个输出口,这和第一个例子一样,定义两个常量。

#define kfilename @"archive"
#define kDataKey @"Data"

打开IP_11persistence2VIEwController.m导入fourlines类。

#import "fourlines.h"

修改代码

-(Nsstring *)datafilePath//用来返回数据文件的完整路径名
{
NSArray *path = NSSearchPathForDirectorIEsInDomains(NSdocumentDirectory,YES);
Nsstring *paths = [path objectAtIndex:0];
return [paths stringByAppendingPathComponent:kfilename];
}

-(voID)applicationWillTerminate:(NSNotification *)notification//应用程序在退出时调用,将数据保存到数据列表
{
fourlines *fourline = [[fourlines alloc] init];
fourline.show1 = show1.text;
fourline.show2 = show2.text;
fourline.show3 = show3.text;
fourline.show4 = show4.text;

NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:fourline forKey:kDataKey];
[archiver finishEnCoding];
[data writetofile:[self datafilePath] atomically:YES];
[fourline release];
[archiver release];
[data release];
}

-(voID)vIEwDIDLoad
{
Nsstring *filePath = [self datafilePath];//得到文件路径
if([[NSfileManager defaultManager] fileExistsAtPath:filePath])//如果该文件存在就加载
{
NSMutableData *data = [[NSMutableData alloc] initWithContentsOffile:[self datafilePath]];
NSKeyedUnarchiver *archiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
fourlines *fourline = [archiver decodeObjectForKey:kDataKey];
[archiver finishDeCoding];

show1.text = fourline.show1;
show2.text = fourline.show2;
show3.text = fourline.show3;
show4.text = fourline.show4;

[archiver release];
[data release];
}
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addobserver:self selector:@selector(applicationWillTerminate:)
name:UIApplicationWillTerminateNotification
object:app];
[super vIEwDIDLoad];
}

对IP_11persistence2VIEwController.xib的 *** 作同第一个。

下面来创建最后一个使用sqlite来保存数据。我创建的项目名是IP_11sqlite。

首先导入libsqlite3.lib,这和导入FrameWork一样,在Framework文件夹上面右击,ADD-Existing files然后选择文件,该文件在/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.sdk/usr/lib/libsqlite3.dylib下面。导入后开始修改代码。

打开IP_11sqliteVIEwController.h

#import "/usr/include/sqlite3.h"
#define kfilename @"data.sqlite3"

增加一个变量:sqlite3 *database;

修改后为:

#import <UIKit/UIKit.h>
#import "/usr/include/sqlite3.h"
#define kfilename @"data.sqlite3"

@interface IP_11sqliteVIEwController : UIVIEwController {
IBOutlet UITextFIEld *show1;
IBOutlet UITextFIEld *show2;
IBOutlet UITextFIEld *show3;
IBOutlet UITextFIEld *show4;

sqlite3 *database;
}
@property (nonatomic,retain) UITextFIEld *show1;
@property (nonatomic,retain) UITextFIEld *show2;
@property (nonatomic,retain) UITextFIEld *show3;
@property (nonatomic,retain) UITextFIEld *show4;
-(Nsstring *)datafilePath;
-(voID)applicationWillTerminate:(NSNotification *)notification;
@end

然后打开IP_11sqliteVIEwController.m修改代码如下:

-(Nsstring *)datafilePath//用来返回数据文件的完整路径名
{
NSArray *path = NSSearchPathForDirectorIEsInDomains(NSdocumentDirectory,YES);
Nsstring *paths = [path objectAtIndex:0];
return [paths stringByAppendingPathComponent:kfilename];
}

-(voID)applicationWillTerminate:(NSNotification *)notification//应用程序在退出时调用,将数据保存到数据列表
{
for(int i = 1; i<=4; i++)
{
Nsstring *fIEldname = [[Nsstring alloc] initWithFormat:@"show%d",i];
UITextFIEld *fIEld = [self valueForKey:fIEldname];//根据每一i的值设定相应textfIEld
[fIEldname release];

Nsstring *update = [[Nsstring alloc] initWithFormat:@"insert or replace into fIElds (row,fIEld_data) values (%d,'%@');",field.text];//插入或更新表
char *errorMsg;

if(sqlite3_exec(database,[update UTF8String],NulL,&errorMsg) != sqlITE_OK)//执行插入或更新 *** 作,如果插入或更新失败给出错误信息
{
NSAssert1(0,@"Error updating tables: %s",errorMsg);
sqlite3_free(errorMsg);
}
}
sqlite3_close(database);//关闭数据库连接
}

-(voID)vIEwDIDLoad
{
if(sqlite3_open([[self datafilePath] UTF8String],&database) != sqlITE_OK)//打开数据库,如果打开失败给出提示
{
sqlite3_close(database);
NSAssert(0,@"Failed to open database");
}

char *errorMsg;
Nsstring *createsql = @"create table if not exists fIElds (row integer primary key,fIEld_data text);";//创建表
if(sqlite3_exec(database,[createsql UTF8String],&errorMsg)!=sqlITE_OK)//是否创建成功
{
sqlite3_close(database);
NSAssert1(0,@"Error creating table: %s",errorMsg);
}

Nsstring *query = @"select row,fIEld_data from fIElds order by row";//查找表中的数据,行和每一行对应的值
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(database,[query UTF8String],-1,&statement,nil) == sqlITE_OK)
{
while(sqlite3_step(statement) == sqlITE_ROW)
{
int row = sqlite3_column_int(statement,0);
char *rowData = (char *)sqlite3_column_text(statement,1);

Nsstring *fIEldname = [[Nsstring alloc] initWithFormat:@"show%d",row];
Nsstring *fIEldValue = [[Nsstring alloc] initWithUTF8String:rowData];
UITextFIEld *fIEld = [self valueForKey:fIEldname];
fIEld.text = fIEldValue;
[fIEldname release];
[fIEldValue release];
}
sqlite3_finalize(statement);
}

UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addobserver:self selector:@selector(applicationWillTerminate:)
name:UIApplicationWillTerminateNotification
object:app];
[super vIEwDIDLoad];
}
最后就是IP_11sqliteVIEwController.xib的修改了,和第一个一样的。

到此三种方法的 *** 作结束了。

总结

以上是内存溢出为你收集整理的phone开发基础教程》第十一章 基本数据持久全部内容,希望文章能够帮你解决phone开发基础教程》第十一章 基本数据持久所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1178011.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存