iOS-数据的持久
数据持久性即是将数据永久的存储,这个存储在重新启动计算机时也不会丢失数据。在IOS开发中将数据持久存储到iPhone的文件系统提供和了4个方法:使用属性列表(.plist),对象归档(相当于java里的对象序列化和反序列化),iPhone的嵌入式关系数据库(SQLite3),以及苹果公司提供的持久性工具Core Data。
1.属性列表,在我们很多应用程序中都用到了属性列表,比如说使用属性列表来指定应用程序首选项、使用属性列表来存储表视图中的数据等。从属性列表返回的数据类型是NSArray和NSDictionary,所已只要字典和数组仅包含特定可序列化的对象就可以将NSarray和NSDictionary实例写入属性列表以及从属性列表创建他们。使用writeToFile:atomically:方法将他们存储在属性列表中,可以按照该方法进行序列化的Objective-C类有:NSArray、NSMutableArray、NSDictionary、NSMutableDictionary、NSData、NSMutableData、NSString、NSMutableString、NSNumber、NSDate。下面通过一个列子介绍下属性列表的存储:
-----------------------------------------------------------------------------------------------------------------
#import <UIKit/UIKite.h>
#define kFilename @"data.plist"
@interface PersistenceViewController : UIViewController{
UITextField *field1;
UITextField *field2;
}
@property (nonatomic, retain) IBOutlet UITextField *field1;
@property (nonatomic,retain) IBOutlet UITextField2 *field2;
- (NSString *)dataFilePath;// 可以将kFilename串联到Documents目录的路劲返回一个完整的路径
- (void)applicationWillTerminate:(NSNotification *)notification;
@end
-------------------------------------------------------------------------------------------------------------------------------------
#import "PersistenceViewController.n"
@implementation PersistenceViewController
@synthesize field1,field2;
- (NSString *)dataFilePath{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0);
return [documentsDirectory stringByAppendingPathComponent:kFilename];
}
- (void) applicationWillTerminate:(NSNotification *)notification{
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:field1.text];
[array addObject:fiels2.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];
field1.text = [array objecyAtIndex:0];
field2.text = [array objectAtIndex:1];
[array release];
}
/*订阅通知并告知通知中心在收到通知时调用指定的方法*/
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationTerminate:) name:UIApplicationWillTerminateNotification object:app];
[super viewDidLoad];
}
............
------------------------------------------------------------------------------------------------------------------------------
2.对象归档:相当于对象序列化和反序列化。基本数据我们可以使用属性列表持久化,那么我们自己定义的类型该怎么办呢?现在我们就使用对象归档的方法来持久化我们自定义的类型。
-------------- 先是自定义一个自己的类 需要继承 NSCoding和NSCopying 接口---------------------------------------------------
#import <Foundation/Foundation.h>
@interface TwoLines : NSObject <NSCoding,NSCopying> {
}
@property (nonatomic,retain) NSString *field1;
@property (nonatomic,retain) NSString *field2;
@end
#import "TwoLines.h"
#define kField1Key @"Field1"
#define kField2Key @"Field2"
@implementation TwoLines
@synthesize field1, field2;
- (void) encodeWithCoder:(NSCoder *)aCoder{ // 编码
[aCoder encodeObject:field1 forKey:kField1Key];
[aCoder encodeObject:field2 forKey:kField2Key];
}
- (id)initWithCoder:(NSCoder *)aDecoder{ // 解码
if (self = [super init]) {
field1 = [[aDecoder decodeObjectForKey:kField1Key] retain];
field2 = [[aDecoder decodeObjectForKey:kField2Key] retain];
}
return self;
}
- (id)copyWithZone:(NSZone *)zone{ // 复制
TwoLines*copy = [[[self class] allocWithZone:zone] init];
copy.field1 = [[self.field1 copyWithZone:zone] autorelease];
copy.field2 = [[self.field2 copyWithZone:zone] autorelease];
return copy;
}
- (void)dealloc{
[field1 release];
[field2 release];
[super dealloc];
}
@end
------------下面是一个controller 来实现如何持久化自定义类-------------------------------------------------------
#import <UIKit/UIKit.h>
#define kFilename @"archive"
#define kDataKey @"Data"
@interface PersistenceViewController : UIViewController {
}
@property (nonatomic,retain) IBOutlet UITextField *field1;
@property (nonatomic,retain) IBOutlet UITextField *field2;
- (NSString *)dataFilePath;
- (void)applicationWillResignActive:(NSNotification *)notification;
@end
--------------------------------------------------------------------------------------------------------------------------
#import "PersistenceViewController.h"
#import "TwoLines.h"
@implementation PersistenceViewController
@synthesize field1,field2;
- (NSString *)dataFilePath{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSLog(@"Document Path:%@",documentsDirectory);
return [documentsDirectory stringByAppendingPathComponent:kFilename];
}
- (void)viewDidLoad {
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSData *data = [[NSMutableData alloc] initWithContentsOfFile:filePath];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
TwoLines *twoLines= [unarchiver decodeObjectForKey:kDataKey];
[unarchiver finishDecoding];
field1.text = twoLines.field1;
field2.text = twoLines.field2;
[unarchiver release];
[data release];
}
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:)
name:UIApplicationWillResignActiveNotification object:app];
[super viewDidLoad];
}
- (void) applicationWillResignActive:(NSNotification *)notification{
TwoLines *twoLine = [[TwoLines alloc] init];
twoLine.field1 = field1.text;
twoLine.field2 = field2.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];
[twoLinerelease];
[data release];
[archiver release];
}
- (void)viewDidUnload {
self.myOutlet = nil;
}
- (void)dealloc {
[field1 release];
[field2 release];
[super dealloc];
}
@end
下一节介绍sqlite3